Qeasy Cloud
Get Started

Production Report Sync in Practice: Engineering the Pull from Kingdee Cloud to Qeasy DataHub

· 系统管理员· Integration Solutions· 16 views· 4 min read
MySQLKingdee Cloud生产同步轻易云Incremental SyncWebAPIMES

What This Strategy Solves

In one discrete manufacturing project, MES lives in MySQL while ERP runs on Kingdee Cloud. Production reports are entered by the shop floor in MES, but they need to be persisted in ERP as queryable, auditable documents. We used Qeasy (轻易云数据集成平台) to implement the "GH Production Report Query" strategy. In essence, it periodically pulls existing production reports from Kingdee Cloud into the integration platform, where they become the data source for reconciliation, status write-back, and shop-floor dashboards. It looks like a simple "query," but in practice you have to design the WebAPI invocation, the incremental cursor, the field alignment, and the schedule carefully to keep it stable.

Data Flow and Field Mapping

The data flow is a one-way pull: Kingdee Cloud → Qeasy DataHub (intermediate layer) → downstream consumers (reconciliation table / status sync / MES write-back).

Business MeaningKingdee Cloud FieldQeasy Intermediate FieldNotes
Bill primary keyFIDidIdempotency key
Bill numberFBillNonumberExternal identifier
Entry primary keyFEntity_FEntryIDentry_idBody-row identifier
Source production orderFMoBillNomo_bill_noTraceability
Material codeFMaterialId.FNumbermaterial_codeNested object must be flattened

Note that FMaterialId in Kingdee Cloud is a base-data field that returns a nested object with FNumber. You must flatten it to material_code in the intermediate layer, otherwise downstream reconciliation will fail.

How to Configure It in Qeasy

The source is Kingdee Cloud's executeBillQuery WebAPI, POST method, QUERY effect. A few key points when configuring in Qeasy:

  1. API selection: Kingdee Cloud's executeBillQuery supports custom return fields. Be sure to include FID, FBillNo, FEntity_FEntryID, FMoBillNo, and FMaterialId.FNumber. Without FBillNo, downstream reconciliation cannot locate bills.
  2. Enable idCheck: The source metadata explicitly sets idCheck: true. Always enable idempotency checks to avoid duplicate rows on re-pull.
  3. Target is a "no-op write": The target API is configured as a no-op write, POST method, EXECUTE effect. This is a common Qeasy pattern—persist to the intermediate table only, do not push directly downstream. It fits a layered "query + persist" design.
  4. Centralized code mapping: Material codes, organization codes, and other base data should be maintained centrally in Qeasy's mapping module, not scattered across strategies. This is the most common pattern among Qeasy customers—one change propagates everywhere later.

Implementation Steps

We split the rollout into three phases to avoid hammering Kingdee Cloud with high-frequency schedules from day one.

  • Step 1: Align the incremental cursor. Use Kingdee Cloud's FModifyDate or FDate as the incremental watermark. Backfill the past 3 days first, validate field mapping, and confirm row counts.
  • Step 2: Run a one-time full pull. Pull all historical production reports without a time window. After it completes, record the maximum FID as the new incremental starting point.
  • Step 3: Switch on the schedule. The source crontab is */2 * * * *—the query fires every 2 minutes. The target write runs on */10 7-22 * * *—writes only during work hours, every 10 minutes. This "high-frequency polling at the source, work-hour landing at the target" dual-track pattern is a mature convention among Qeasy customers: near-real-time on the source, but no overnight writes filling up the database.

Lessons Learned (Reactive Post-mortem)

  • Mistake 1: Ignoring the nested FMaterialId.FNumber. Pulling FMaterialId as a plain string causes downstream reconciliation to fail. The safe approach is to flatten it on the source side, or write a transformation script in Qeasy's field mapping.
  • Mistake 2: Crontab set too aggressively. */2 is an empirical value; some teams shorten it to */1 and immediately hit Kingdee Cloud's rate limits. The safe approach is to run */2 for a week first, observe response-time distribution, and then decide whether to tighten it.
  • Mistake 3: Writing into real business tables at the target. The target is intentionally a no-op. If you mistakenly point it at a real business table, header and body rows can land in separate transactions and leave dirty data. The safe pattern is phased landing—write the header first, then the body asynchronously, with retry on failure.
  • Mistake 4: idCheck not enabled. Kingdee Cloud's query API has no built-in deduplication. Without idCheck, the same FBillNo appears multiple times in the intermediate table.
  • Mistake 5: No gap handling across midnight. The source runs */2 all day, but the target only lands during 7-22 on a */10 schedule. Anything pulled at 22:10 will not be persisted until 7:00 the next morning—a 9-hour lag. The safe fix is either to extend the target to */10 around the clock, or to add a "night-accumulation" filter on the source side.

When This Fits and When It Doesn't

Fits: Shop floors that record production reports in MES and need them reconciled or audited in ERP; organizations that already run Kingdee Cloud as their ERP and want a clean intermediate layer for distribution.

Doesn't fit: Scenarios that need sub-second real-time push to ERP—use Kingdee Cloud's real-time API instead of polling. Also not suitable when the source is not Kingdee Cloud, or when the target must be a real business table—this strategy is designed for intermediate-layer persistence only.

Original content. Please credit the source when reposting: /insights/solutions/strat-mysql-kingdee-cloud-2246-gh-a181f16f

Comments