数据集成:从旺店通到金蝶云星空的最佳实践

  • 轻易云集成顾问-谢楷斌
### 旺店通·旗舰奇门数据集成到金蝶云星空的案例分享 在实现旺店通·旗舰奇门与金蝶云星空的数据对接过程中,我们面临着多种技术挑战。本文将详细剖析如何利用API接口wdt.wms.stockother.outquery.querywithdetail从旺店通·旗舰奇门获取其他出库单数据,并通过batchSave接口实现批量写入金蝶云星空,确保高效、可靠的数据传输和处理。 #### 1. 保证不漏单的数据获取 为了准确无误地抓取所有必要的其他出库单数据,我们设计了一个定时任务,通过调用`wdt.wms.stockother.outquery.querywithdetail`接口进行周期性抓取。这个过程需要特别小心的地方在于分页和限流问题,为此我们采用了分布式锁机制配合分页拉取策略,避免由于短时间大量请求而导致的接口限流,同时确保每一页数据全部成功获取: ```python def fetch_stockout_data(page_number, page_size): while True: response = requests.get( url="https://api.example.com/wdt.wms.stockother.outquery.querywithdetail", params={"page": page_number, "pageSize": page_size} ) if response.status_code == 200: data = response.json() process_data(data) if len(data) < page_size: break else: handle_api_error(response) fetch_stockout_data(1, 100) ``` #### 2. 数据格式差异转换与映射 处理两套系统之间的数据格式差异是另一个关键环节。在实际操作中,对从旺店通·旗舰奇门获取的数据进行必要的清洗、转换,以契合金蝶云星空所需的格式。这包括字段名转换、数据类型变化以及逻辑上的一致性校验。例如,将日期格式统一为ISO标准并确保字段名称匹配: ```python def transform_format(raw_data): transformed_data = [] for record in raw_data: transformed_record = { "Date": convert_date_to_iso(record["date"]), "OrderID": record["order_id"], # 映射更多字段... } transformed_data.append(transformed_record) return transformed_data cleaned_data = transform_format(fetched_raw_data) ``` #### 3. 实现批量、高速写入金蝶云星空 为了提升大规模数据写入效率,使用 `batchSave` API 批量提交整理好的其他出库单信息至 金蝶 云 星空。在这一环节,我们设立重试机制以应对偶发性错误,并实时记录日志以监控整个流程进展及异常情况: ```python def batch_save ![金蝶与外部系统打通接口](https://pic.qeasy.cloud/D27.png~tplv-syqr462i7n-qeasy.image) ### 调用源系统旺店通·旗舰奇门接口获取并加工数据 在数据集成生命周期的第一步,我们需要从源系统获取数据,并对其进行初步的清洗和加工。本文将详细介绍如何通过调用旺店通·旗舰奇门接口`wdt.wms.stockother.outquery.querywithdetail`来实现这一过程。 #### 接口调用配置 该接口使用POST方法,主要用于查询其他出库单的详细信息。以下是元数据配置的详细说明: ```json { "api": "wdt.wms.stockother.outquery.querywithdetail", "method": "POST", "number": "other_out_no", "id": "other_out_no", "idCheck": true, "request": [ { "field": "params", "label": "查询参数", "type": "object", "children": [ { "field": "time_type", "label": "时间类型", "type": "string", "describe": "1:创建时间;2:最后修改时间 不传默认为创建时间" }, { "field": "start_time", "label": "开始时间", "type": "string", "describe": "起始时间,若无业务单号,则为必填。yyyy-MM-dd HH:mm:ss格式", "value": "_function DATE_SUB(now(),INTERVAL 15 DAY)" }, { "field": "end_time", "label": "结束时间", "type": "string", "describe": "结束时间,上同开始时间.", "value": "{{CURRENT_TIME|datetime}}" }, { ... } ] }, { ... } ] } ``` #### 请求参数详解 1. **params**: 查询参数对象,包含以下字段: - **time_type**: 时间类型,1表示创建时间,2表示最后修改时间。如果不传,则默认为创建时间。 - **start_time**: 起始时间,格式为`yyyy-MM-dd HH:mm:ss`。如果没有业务单号,则此字段为必填项。默认值为当前时间减去15天。 - **end_time**: 结束时间,与开始时间格式相同。默认值为当前系统时间。 - **warehouse_no**: 仓库编号,用于指定查询的仓库。 - **other_out_no**: 业务单号,用于精确查询特定的出库单。 - **status**: 业务单据状态,多个状态值用逗号分隔。例如:65表示待结算,70表示已完成。 2. **pager**: 分页参数对象,包含以下字段: - **page_size**: 每页记录数,默认值为10。 - **page_no**: 页码,从1开始。 #### 数据请求与清洗 在调用接口获取数据后,需要对返回的数据进行初步清洗和加工,以便后续的数据转换和写入步骤。以下是一个示例代码片段,用于展示如何处理接口返回的数据: ```python import requests import json from datetime import datetime, timedelta # 定义请求URL和头部信息 url = 'https://api.wangdian.cn/openapi2/wdt.wms.stockother.outquery.querywithdetail' headers = {'Content-Type': 'application/json'} # 定义请求参数 params = { 'time_type': '1', 'start_time': (datetime.now() - timedelta(days=15)).strftime('%Y-%m-%d %H:%M:%S'), 'end_time': datetime.now().strftime('%Y-%m-%d %H:%M:%S'), 'warehouse_no': '', 'other_out_no': '', 'status': '65,70' } pager = { 'page_size': '10', 'page_no': '1' } # 构建请求体 data = { 'params': params, 'pager': pager } # 发起POST请求 response = requests.post(url, headers=headers, data=json.dumps(data)) # 检查响应状态码 if response.status_code == 200: result = response.json() # 数据清洗与加工 cleaned_data = [] for record in result['data']: cleaned_record = { 'out_no': record['other_out_no'], 'warehouse': record['warehouse_no'], ... } cleaned_data.append(cleaned_record) # 输出清洗后的数据 print(json.dumps(cleaned_data, indent=4)) else: print(f"Error: {response.status_code}") ``` #### 总结 通过上述步骤,我们成功调用了旺店通·旗舰奇门接口`wdt.wms.stockother.outquery.querywithdetail`并对返回的数据进行了初步清洗和加工。这一步骤是数据集成生命周期中的关键环节,为后续的数据转换与写入奠定了基础。在实际应用中,可以根据具体需求进一步优化和扩展数据处理逻辑,以满足不同业务场景的要求。 ![金蝶与SCM系统接口开发配置](https://pic.qeasy.cloud/S21.png~tplv-syqr462i7n-qeasy.image) ### 使用轻易云数据集成平台实现金蝶云星空API接口的数据ETL转换 在数据集成生命周期的第二步中,我们需要将已经集成的源平台数据进行ETL(提取、转换、加载)转换,使其符合目标平台金蝶云星空API接口的要求,并最终写入目标平台。本文将详细探讨如何通过轻易云数据集成平台实现这一过程。 #### 配置元数据 首先,我们需要配置元数据以便与金蝶云星空API接口进行交互。以下是一个典型的元数据配置示例: ```json { "api": "batchSave", "method": "POST", "idCheck": true, "operation": { "rowsKey": "array", "rows": 1, "method": "batchArraySave" }, "request": [ {"field":"FBillNo","label":"单据编号","type":"string","describe":"单据编号","value":"{other_out_no}"}, {"field":"FBillTypeID","label":"单据类型","type":"string","describe":"单据类型","parser":{"name":"ConvertObjectParser","params":"FNumber"},"value":"{reason}","mapping":"62e8ddee55eec0316710dab6","mappingDirection":"positive"}, {"field":"FStockOrgId","label":"库存组织","type":"string","describe":"组织","parser":{"name":"ConvertObjectParser","params":"FNumber"},"value":"100"}, {"field":"FPickOrgId","label":"领用组织","type":"string","describe":"组织","parser":{"name":"ConvertObjectParser","params":"FNumber"},"value":"100"}, {"field":"FStockDirect","label":"库存方向","type":"string","describe":"下拉列表"}, {"field":"FDate","label":"日期","type":"string","describe":"日期","value":"{{modified|datetime}}"}, {"field":"FCustId","label":"客户","type":"string","describe":"基础资料","parser":{"name":"ConvertObjectParser","params":"FNumber"}}, {"field":"FDeptId","label":"领料部门","type": "string", "describe": "基础资料", "parser": { "name": "ConvertObjectParser", "params": "FNumber" }, "value": "{prop1}", "mapping": "62e8d45581cfb6359213a5b7", "mappingDirection": "positive" }, {"field": "FPickerId", "label": "领料人", "type": "string", "describe": "基础资料", "parser": { "name": "ConvertObjectParser", "params": "FNumber" } }, {"field": "FBizType", "label": “业务类型”, “type”: “string”, “describe”: “下拉列表”}, {"field”: “FOwnerTypeIdHead”, “label”: “货主类型”, “type”: “string”, “describe”: “多类别基础资料列表”, “value”: “BD_OwnerOrg”}, {"field”: “FOwnerIdHead”, “label”: “货主”, “type”: “string”, “describe”: “多类别基础资料”, “parser”: {“name”:“ConvertObjectParser”,“params”:“FNumber”},“value”:“100”}, {"field”:“FNote”,“label”:“备注”,“type”:“string”,“describe”:”多行文本“,“value”:”{remark}”}, { ”field”:”FEntity”, ”label”:”明细信息”, ”type”:”array”, ”children”:[ {”field”:”FMaterialId”,”label”:”物料编码”,”type”:”string”,”describe”:”基础资料”,”parser”:{”name”:”ConvertObjectParser”,”params”:”FNumber”,},”value”:{{detail_list.goods_no}},”parent”:”FEntity”,}, {”field”:”FCMKBarCode”,"label":"零售条形码","type":"string","describe":"文本","parent":"FEntity"}, { ” field ”: ” FQty ”, ” label ”: ” 实发数量 ”, ” type ”: ” string ”, ” describe ”: ” 数量 ”, ” value : {{ detail_list.num }} , parent : FEntity , }, { field : FStockId , label : 发货仓库 , type : string , describe : 基础资料 , parser : name : ConvertObjectParser , params : FNumber , value : warehouse_no , parent : FEntity , }, { field : FStockLocId , label : 仓位 , type : string , describe : 维度关联字段 , parser : name : ConvertObjectParser , params : FNumber , parent : FEntity , }, { field : FAmount , label : 总成本 , type : string , describe 金额 parent FEntity }, { field : FPrice , label : 成本价 , type : string , describe : 单价 , parent : FEntity }, { field : FSrcBillTypeId , label : 源单类型 , type : string , describe : 源单类型 , parent : FEntity }, { field : FSrcBillNo , label : 源单编号 , type : string , describe : 源单编号 , parent : FEntity }, { field : FOwnerTypeId , label : 货主类型 , type : string , describe 多类别基础资料列表 value BD_OwnerOrg parent FEntity }, { field :FOwnerId, label:货主, type:string, describe:多类别基础资料, value:100, parent:FEntity, parser:{ name: ConvertObjectParser, params: FNumber }}, { field: FEntryNote, label:备注, type:string, describe:多行文本, parent:FEntity } ], value:detail_list, } ], otherRequest:[ { field:FormId, label:业务对象表单 Id, type: string, describe 必须填写金蝶的表单 ID 如 PUR_PurchaseOrder, value STK_MisDelivery, }, { field IsAutoSubmitAndAudit, label 提交并审核, type bool, value false, }, { field IsVerifyBaseDataField, label 验证基础资料, type bool, describe 是否验证所有的基础资料有效性,布尔类,默认 false(非必录), value true, }, { field Operation, label 执行的操作, type string, value Save, } ] } ``` #### 数据提取与清洗 在数据提取阶段,我们从源系统获取原始数据。该过程通常包括从数据库或API中提取数据,并对其进行初步清洗和标准化处理,以确保后续步骤能够顺利进行。 #### 数据转换 在数据转换阶段,我们将清洗后的数据按照目标平台金蝶云星空API接口的要求进行格式转换。这一步至关重要,因为不同系统之间的数据格式和结构可能存在显著差异。 1. **字段映射与解析**: - 使用`ConvertObjectParser`解析器将源系统中的字段值转换为目标系统所需的格式。例如,将`reason`字段映射为`FBillTypeID`,并使用`mapping`参数指定具体的映射规则。 - 对于复杂的数据结构,如数组或嵌套对象,可以通过配置`children`字段来处理。例如,明细信息(`FEntity`)中的每个子项都需要进行相应的解析和映射。 2. **日期与时间格式**: - 使用模板语法(如`{{modified|datetime}}`)将日期和时间字段转换为目标系统所需的格式。 3. **静态值设置**: - 对于某些固定不变的字段,可以直接在元数据配置中设置静态值。例如,将库存组织(`FStockOrgId`)和领用组织(`FPickOrgId`)设置为固定值 `100`。 #### 数据加载 在完成数据转换后,我们使用配置好的API接口将处理后的数据写入目标平台金蝶云星空。通过调用配置中的API方法(如 `batchSave`),并传递处理后的请求参数,实现最终的数据加载。 ```json { api: 'batchSave', method: 'POST', idCheck: true, operation: { rowsKey: 'array', rows: 1, method: 'batchArraySave' }, request: [ // 已处理好的请求参数 ], otherRequest:[ { field:'FormId', label:'业务对象表单 Id', type:'string', describe:'必须填写金蝶的表单 ID 如 PUR_PurchaseOrder', value:'STK_MisDelivery' }, { field:'IsAutoSubmitAndAudit', label:'提交并审核', type:'bool', value:false }, { field:'IsVerifyBaseDataField', label:'验证基础资料', type:'bool', describe:'是否验证所有的基础资料有效性,布尔类,默认 false(非必录)', value:true }, { field:'Operation', label:'执行的操作', type:'string', value:'Save' } ] } ``` 通过上述步骤,我们成功地将源平台的数据经过ETL转换后写入到金蝶云星空,实现了不同系统间的数据无缝对接。 ![钉钉与CRM系统接口开发配置](https://pic.qeasy.cloud/T8.png~tplv-syqr462i7n-qeasy.image)