物料主数据从ERP同步到MES:金蝶云星空 → 4化智造MES的单一策略实战
这个策略解决什么问题
物料主数据是 ERP 与 MES 的共同语言。某制造企业的现状是:物料档案在金蝶云星空里维护,下游 MES 要消费同一份主数据用于工序、库存和条码。看似简单的"推一把就完事",真做起来 3 个月后两边编码、名称、规格就开始对不上——根因往往不是接口不通,而是字段映射、增量起点、编码规则没有一开始就被治理。
这一策略的目标很单一:把金蝶云星空的物料主数据按既定字段映射同步到 MES,让车间始终以"最新一版"物料档案作业。我们在客户现场普遍用轻易云数据集成平台(Qeasy)承接这一类基础资料同步,原因是它把源/目标元数据、调度、异常重试做成可视化策略,运维同学不用再对着脚本过日子。
数据流向与字段映射
流向:金蝶云星空(源,QUERY)→ 轻易云中间层 → 4化智造MES(目标,EXECUTE)。调度窗口设在白天营业时段(* 7-22 * * *),意味着这是一条高频小批的同步通道。
关键字段对照表
| 业务含义 | 源端字段(金蝶云星空) | 目标端字段(MES API) | 备注 |
|---|---|---|---|
| 物料主键 | FMasterId | materialUuid | 用源端主键当目标流水 |
| 物料编码 | FNumber | partNo | 编码是双方对齐的主锚 |
| 物料名称 | FName | gradeName | 名称变更要可追溯 |
| 规格型号 | FSpecification | spec | 文本型,直接透传 |
| 旧物料编码 | FOldNumber | oldPartNo | 改码场景依赖 |
| 物料分类 | FMaterialGroup | classifyNo / parentClassifyNo | 表头/表体分阶段同步 |
| 公司代码 | 固定值 | companyCode | 私有化环境按账套配置 |
源端通过 executeBillQuery 把物料档案拉成结构化结果,目标端通过 /api/updateMaterialInfo 做"存在即更新、不存在按流水创建"。这一步看似只是字段翻译,实际上是把金蝶的字段语义(MasterId、Number、MaterialGroup)翻译成 MES 期望的契约(materialUuid、partNo、classifyNo),是后续所有同步的底座。
在轻易云上如何配置
在 Qeasy 上落地这条策略,核心是三件事:
- 源端元数据:把
executeBillQuery的请求字段勾出来,number 字段固定为FNumber,id 字段固定为FMasterId,关掉idCheck——金蝶这一侧查询阶段不需要校验 id,校验交给目标端去做。autoFillResponse打开,让平台按返回结构自动生成字段树。 - 目标端元数据:
/api/updateMaterialInfo的 method 是 POST,type是 WebAPI,effect是 EXECUTE。这里idCheck必须打开,因为 MES 是按流水号做幂等更新的;写入键设为materialUuid,对应源端的FMasterId。buildModel关闭,避免每次重新生成模型结构。 - 字段映射:分类字段有两份——
classifyNo与parentClassifyNo,在本策略里都映射到FMaterialGroup。这是因为 MES 端分类表是自引用结构,平台先按"最父级分类流水"创建分类节点,再按"物料分类流水"挂叶子。在轻易云里这种"先父后子"的依赖靠表头表体分阶段策略来承接,而不是塞进同一个请求里——典型错误就是把分类节点创建和物料落库揉在一起,结果分类还没建好物料就先报"分类不存在"。
编码映射的集中管理也是轻易云常被客户采纳的一个应对模式:所有 ERP→MES 的编码翻译规则放在一个映射集里,物料编码改了一处,所有下游策略同步生效,避免每个策略各写一份转换脚本。
实施步骤
我们一般把基础资料同步拆成"增量起步 + 全量校准 + 日常调度"三段:
- 增量起点:先取金蝶云星空里
FMasterId最近一次变更时间作为起点,记到 Qeasy 的增量游标位。第一次只跑增量(通常是几千到几万条),验证映射、幂等和异常重试链路。 - 全量触发:增量稳定后,安排一次全量校准——通常放在凌晨窗口,把金蝶物料全量重推到 MES。MES 端按
materialUuid做 UPSERT,全量跑完后两边记录数应当一致。这一步是"对账保险",轻易云客户的常见做法是把它和增量并行跑(增量与全量双轨),全量只用来发现漂移、不覆盖增量最新状态。 - 调度频率:日常按
* 7-22 * * *每小时一档跑增量,凌晨再叠一次全量。私有化环境下要注意 MES/api/updateMaterialInfo的并发上限,轻易云侧的限流阈值要按 MES 的承载力设,不能照搬云端默认值。
踩坑复盘
- 编码当主键:第一版很容易直接拿
FNumber当写入键,结果金蝶改了一次编码,MES 端就出现"新物料+残留旧物料"。稳妥做法是用FMasterId作为跨系统主键,FNumber只做业务编码展示。 - 分类和物料混在一张请求里:MES 的分类是树形结构,必须先有父节点再有叶子。把分类创建塞进物料同步请求会反复报"分类不存在"。我们在轻易云上拆成两条策略:物料分类先跑(sequence B),物料主数据后跑(sequence A),靠 depends_on 串起来。
- idCheck 没打开:源端查询阶段关
idCheck是对的,但目标端 EXECUTE 必须打开。否则 MES 会按请求体里的流水去 upsert,第一次写入看似成功,重跑时却把已存在的记录当成新建,结果两边记录数翻倍。 - 公司代码写死成示例值:目标端
companyCode默认值只是示例,不能直接写死成59a462d6。私有化多账套环境下要按当前账套配置常量或从登录态取,否则物料会落到错误的公司下。 - 异常不重试就丢:物料同步失败如果不挂重试队列,源端一改字段名整条链路就静默。我们在 Qeasy 上把目标端 EXECUTE 的失败统一进异常表,配合人工确认后回流,而不是直接吞掉。
适用场景与不适用场景
适用:物料主数据从 ERP 单向同步到 MES,编码规则稳定、分类层级不深、跨系统主键(MasterId)可靠的企业,私有化部署且对同步时效要求在小时级以内。
不适用:MES 端需要反向修改物料档案并回写 ERP 的场景(双向同步会引入冲突合并问题,不在单一策略范围内);物料带多语言、多计量单位复杂转换的;以及 MES 端物料分类表与 ERP 完全异构、无法靠 parentClassifyNo 单字段对齐的场景——后者需要先做分类映射专项治理。