利用轻易云平台实现金蝶云星空到MySQL的数据融合

  • 轻易云集成顾问-钟家寿
### 金蝶云星空数据集成MySQL技术案例:MOM-XSDD-销售订单-表体-状态刷新 在业务系统高度依赖实时数据更新的背景下,如何高效地将金蝶云星空的数据集成到MySQL成为一个关键技术挑战。本文通过分享"MOM-XSDD-销售订单-表体-状态刷新"这一实际运行的方案,为大家揭示实现这一目标的具体技术细节与操作步骤。 首先,在进行数据集成前,需要先了解金蝶云星空接口`executeBillQuery`和MySQL写入接口`execute`的使用方法。通过调用金蝶云星空API,我们可以获取完整且精准的销售订单数据。在此过程中,处理分页和限流问题尤为重要,以确保不漏单并优化请求响应效率。 其次,对于大量的数据导出,平台支持高吞吐量的数据写入能力,这意味着可以快速批量将从金蝶云星空获取到的数据写入MySQL数据库,大大提升了数据处理时效性。这一步中,自定义数据转换逻辑便显得尤为必要,因为需要适应两者间不同的业务需求和数据结构。 为了确保整个流程顺利开展,还需特别注意以下几点: 1. **定时可靠抓取**:通过调度任务定期调用金蝶云星空API以获取最新销售订单信息,并保证这些任务具有一定容错机制,如异常重试功能。 2. **集中监控与告警**:利用平台提供的监控系统,可以实时跟踪每个数据集成任务,从而快速定位可能存在的问题。 3. **自定义映射规则**:在写入MySQL之前,通过映射配置工具对获得的数据进行调整,以适应其数据库表结构,并保证一致性、准确性。 紧接着,将详细介绍如何编排上述各环节,使得整个过程透明且易于管理。同时,我们也会探讨解决GoldSky API与MySQL之间格式差异以及错误处理机制的方法,确保在面对复杂环境变化时仍能稳健运行。 ![如何开发钉钉API接口](https://pic.qeasy.cloud/D21.png~tplv-syqr462i7n-qeasy.image) ### 调用金蝶云星空接口executeBillQuery获取并加工数据 在数据集成的生命周期中,第一步是从源系统获取数据。本文将详细介绍如何通过轻易云数据集成平台调用金蝶云星空接口`executeBillQuery`,获取并加工销售订单表体状态刷新相关的数据。 #### 接口配置与请求参数 为了实现这一目标,我们需要配置元数据,并通过POST方法调用`executeBillQuery`接口。以下是关键的元数据配置: ```json { "api": "executeBillQuery", "effect": "QUERY", "method": "POST", "number": "FBillNo", "id": "FSaleOrderEntry_FEntryID", "name": "FBillNo", "request": [ {"field": "FSaleOrderEntry_FEntryID", "label": "明细实体主键", "type": "string", "describe": "FSaleOrderEntry_FEntryID", "value": "FSaleOrderEntry_FEntryID"}, {"field": "FID", "label": "表头实体主键", "type": "string", "describe": "FID", "value": "FID"}, {"field": "FBillNo", "label": "单据编号", "type": "string", "describe": "单据编号", "value": "FBillNo"}, {"field": "FDocumentStatus", "label": "单据状态", "type": "string", "describe": "单据状态", "value":"FDocumentStatus"}, {"field":"FMaterialId_Fnumber","label":"物料编码","type":"string","describe":"物料编码","value":"FMaterialId.Fnumber"}, {"field":"FTaxPrice","label":"含税单价","type":"string","describe":"含税单价","value":"FTaxPrice"}, {"field":"FAmount","label":"金额","type":"string","value":"FAmount"}, {"field":"FAllAmount","label":"价税合计","type":"string","describe":"价税合计","value":"FAllAmount"}, {"field":"FSaleOrderEntry_fseq","label":"明细行号","type":"string","value":"FSaleOrderEntry_fseq"}, {"field":"FMrpCloseStatus","label":"业务关闭","type":"string","describe":"业务关闭","value":"FMrpCloseStatus"}, {"field":"FMrpFreezeStatus","label":"业务冻结","type":"string","describe":"业务冻结","value":"FMrpFreezeStatus"}, {"field":"FFreezerId","label":"冻结人","type":"string","describe":"冻结人","value" :"FFreezerId.fname"}, {"field" :"FFreezeDate" ,"label" :"冻结日期" ,"type" :"string" ,"describe" :"冻结日期" ,"value" :"FFreezeDate"}, {"field" :"FMrpTerminateStatus" ,"label" :"业务终止" ,"type" :"string" ,"describe" :"业务终止" ,"value" :"FMrpTerminateStatus"}, {"field" :"FTerminaterId" ,"label" :"终止人" ,"type" :"string" ,"describe" :"终止人" ,"value ":"FTerminaterId.fname"}, {"field ":"FTerminateDate ","label ":"终止日期 ","type ":"string ","describe ":"终止日期 ","value ":"FTerminateDate"}, {"field ":"F_ReplyDeliveryDate ","label ":"回复交期 ","type ":"string ","value ":"F_ReplyDeliveryDate"}, {"field ":"F_ReplyDeliveryDate2 ","label ":"二次回复交期 ","type ":"string ","value ":"F_ReplyDeliveryDate2"}, {"field ":"F_ProductLine ","label ":"产品线 ","type ":"string ","value ":"F_ProductLine"}, {"field ":“ FPrice ”," label ":“ 单价 ”," type ":“ string ”," value ":“ FPrice ”} ], “otherRequest”: [ {“ field”: “ Limit”, “ label”: “最大行数”, “ type”: “ string”, “ describe”: “金蝶的查询分页参数”, “ value”: “5000”}, {“ field”: “ StartRow”, “ label”: “开始行索引”, “ type”: “ string”, “ describe”: “金蝶的查询分页参数”, “ value”: "{PAGINATION_START_ROW}”}, {“ field”: “ TopRowCount”, “ label”: “返回总行数”, “ type”: “ int”, “ describe”: “金蝶的查询分页参数”}, {“ field”:” FilterString”,” label”:”过滤条件”,” type”:” string”,” describe”:”示例写法 FSupplierId.FNumber = 'VEN00010' and FApproveDate>=”,“ value”:” FModifyDate>='{{LAST_SYNC_TIME|dateTime}}' and FDocumentStatus='C'\n-- FDate>='2023-01-01'”}, {“ field”:” FieldKeys”,” label”:”需查询的字段key集合”,” type”:” array”,” describe”:”金蝶分录主键ID格式:FPOOrderEntry_FEntryId,其它格式 FPurchaseOrgId.FNumber”,“ parser”:{“ name”:” ArrayToString”,“ params”:”,"}}, {“ field”:” FormId”,” label”:”业务对象表单Id”,” type”:” string”,” describe”:必须填写金蝶的表单ID如:PUR_PurchaseOrder”,“ value”:SAL_SaleOrder} ], autoFillResponse: true } ``` #### 请求示例 在实际操作中,我们需要构建一个HTTP POST请求,包含上述元数据中的字段和参数。例如: ```json { "_FormId_": { "_Value_": ["SAL_SaleOrder"] }, "_FieldKeys_":{ "_Value_":[ 'FSaleOrderEntry_FEntryID', 'FID', 'FBillNo', 'FDocumentStatus', 'FMaterialId.Fnumber', 'FTaxPrice', 'FAmount', 'FAllAmount', 'FSaleOrderEntry_fseq', 'FMrpCloseStatus', 'FMrpFreezeStatus', 'FFreezerId.fname', 'FFreezeDate', 'FMrpTerminateStatus', 'FTerminaterId.fname', 'FTerminateDate', 'F_ReplyDeliveryDate', 'F_ReplyDeliveryDate2', 'F_ProductLine', 'FPrice' ] }, "_FilterString_":{ "_Value_":[" FModifyDate>='2023-01-01' and FDocumentStatus='C'"] }, "_Limit_":{ "_Value_":["5000"] }, "_StartRow_":{ "_Value_":["0"] } } ``` #### 数据清洗与转换 一旦成功获取到数据,下一步就是进行数据清洗和转换。这一步非常关键,因为源系统的数据格式可能与目标系统不一致,需要进行适当的处理。例如: 1. **字段映射**:将源系统字段映射到目标系统字段。 2. **数据类型转换**:确保所有字段的数据类型符合目标系统要求。 3. **异常处理**:处理可能出现的数据异常,如缺失值或格式错误。 #### 实践案例 假设我们从金蝶云星空成功获取了以下销售订单数据: ```json [ { FSaleOrderEntry_FEntryID: ‘1001’, FID: ‘2001’, FBillNo: ‘SO20230101’, FDocumentStatus: ‘C’, FMaterialId_Fnumber: ‘MAT001’, FTaxPrice: ‘100.00’, FAmount: ‘1000.00’, FAllAmount: ‘1100.00’, ... }, ... ] ``` 我们需要将这些数据转换为目标系统所需的格式,例如: ```json [ { sale_order_entry_id: ‘1001’, order_id: ‘2001’, order_number: ‘SO20230101’, document_status: ‘Completed’, material_code: ‘MAT001’, tax_price: ‘100.00’, amount: ‘1000.00’, total_amount_with_tax: ‘1100.00’ ... }, ... ] ``` 通过轻易云数据集成平台,我们可以使用内置的数据转换工具和脚本语言(如JavaScript)来实现上述转换。 #### 总结 通过调用金蝶云星空接口`executeBillQuery`并进行适当的数据清洗和转换,我们能够高效地获取并处理销售订单表体状态刷新相关的数据。这一步是整个数据集成生命周期中的关键环节,为后续的数据写入和应用奠定了坚实基础。 ![如何对接用友BIP接口](https://pic.qeasy.cloud/S27.png~tplv-syqr462i7n-qeasy.image) ### 数据集成生命周期第二步:ETL转换与写入MySQL API接口 在数据集成的生命周期中,ETL(Extract, Transform, Load)转换是至关重要的一步。本文将深入探讨如何将已经集成的源平台数据进行ETL转换,转为目标平台 MySQL API 接口所能够接收的格式,并最终写入目标平台。 #### 1. 元数据配置解析 元数据配置是实现ETL转换的核心。以下是我们使用的元数据配置: ```json { "api": "execute", "effect": "EXECUTE", "method": "POST", "idCheck": true, "request": [ { "field": "main_params", "label": "main_params", "type": "object", "describe": "111", "value": "1", "children": [ {"field": "MRP_CLOSE_STATUS", "label": "业务关闭", "type": "string", "value": "{FMrpCloseStatus}"}, {"field": "MRP_FREEZE_STATUS", "label": "业务冻结", "type": "string", "value": "{FMrpFreezeStatus}"}, {"field": "FREEZER_NAME", "label": "冻结人", "type": "string", "value": "{FFreezerId}"}, {"field": "FREEZE_DATE", "label": "冻结日期", "type": "string", "value":"_function case '{FFreezeDate}' when '' then null else '{FFreezeDate}' end" }, {"field": "MRP_TERMINATE_STATUS", "label":"业务终止", "type":"string", "value":"{FMrpTerminateStatus}" }, {"field":"TERMINATER_NAME","label":"终止人","type":"string","value":"{FTerminaterId}"}, {"field":"TERMINATE_DATE","label":"终止日期","type":"string","value":"_function case '{FTerminateDate}' when '' then null else '{FTerminateDate}' end"}, {"field":"KINGDEE_ENTRYID1","label":"KINGDEE_ENTRYID1","type":"string","value":"{FSaleOrderEntry_FEntryID}"}, {"field":"SYNC_FLAG","label":"SYNC_FLAG","type":"string","value":"1"} ] } ], "otherRequest":[ { "field":"main_sql", "label":"main_sql", "type":"string", "describe":"111", "value": "update ty_mes.mt_so_line \n set MRP_CLOSE_STATUS=:MRP_CLOSE_STATUS,\nMRP_FREEZE_STATUS=:MRP_FREEZE_STATUS,\nFREEZER_NAME=:FREEZER_NAME,\nFREEZE_DATE=:FREEZE_DATE,\nMRP_TERMINATE_STATUS=:MRP_TERMINATE_STATUS,\nTERMINATER_NAME=:TERMINATER_NAME,\nTERMINATE_DATE=:TERMINATE_DATE,\nSYNC_FLAG=:SYNC_FLAG\nwhere KINGDEE_ENTRYID=:KINGDEE_ENTRYID1" } ] } ``` #### 2. 数据请求与清洗 首先,我们需要从源系统获取原始数据。这一步通常涉及调用源系统API或查询数据库,以获取需要处理的数据。在我们的元数据配置中,`request`字段定义了需要从源系统获取的数据字段及其映射关系。 例如: - `MRP_CLOSE_STATUS` 映射到 `{FMrpCloseStatus}` - `FREEZER_NAME` 映射到 `{FFreezerId}` 这些映射关系确保我们能够准确地从源系统提取所需的数据。 #### 3. 数据转换 在数据转换阶段,我们需要将提取的数据进行格式化和处理,以符合目标平台 MySQL API 接口的要求。这里,我们使用了 `_function case` 来处理日期字段,例如: ```json {"field":"FREEZE_DATE","label":"冻结日期","type":"string","value":"_function case '{FFreezeDate}' when '' then null else '{FFreezeDate}' end"} ``` 这段代码表示,如果 `FFreezeDate` 字段为空,则将其值设为 `null`,否则保持原值。这种处理方式确保了数据的一致性和完整性。 #### 4. 数据写入 最后一步是将处理后的数据写入目标平台。在我们的例子中,目标平台是 MySQL,通过调用 MySQL 的 API 接口来实现数据写入。元数据配置中的 `otherRequest` 字段定义了 SQL 更新语句: ```json { "field":"main_sql", "label":"main_sql", "type":"string", "value": "update ty_mes.mt_so_line \n set MRP_CLOSE_STATUS=:MRP_CLOSE_STATUS,\nMRP_FREEZE_STATUS=:MRP_FREEZE_STATUS,\nFREEZER_NAME=:FREEZER_NAME,\nFREEZE_DATE=:FREEZE_DATE,\nMRP_TERMINATE_STATUS=:MRP_TERMINATE_STATUS,\nTERMINATER_NAME=:TERMINATER_NAME,\nTERMINATE_DATE=:TERMINATE_DATE,\nSYNC_FLAG=:SYNC_FLAG\nwhere KINGDEE_ENTRYID=:KINGDEE_ENTRYID1" } ``` 这段 SQL 更新语句使用占位符 `:` 来绑定参数,例如 `:MRP_CLOSE_STATUS` 对应 `MRP_CLOSE_STATUS` 字段。这种方式确保了 SQL 注入攻击的防范,同时提高了执行效率。 #### 总结 通过上述步骤,我们实现了从源系统提取、清洗、转换并最终写入目标平台 MySQL 的完整流程。关键在于正确理解和应用元数据配置,以确保每个字段都能准确映射和处理,从而保证数据集成过程的高效和可靠。 ![用友与SCM系统接口开发配置](https://pic.qeasy.cloud/T11.png~tplv-syqr462i7n-qeasy.image)