Kingdee AssemblyDisassembly Sub-Item Sync to MySQL: A Single-Strategy Tutorial
What This Strategy Solves
In the supply chain of a manufacturing company, Kingdee Cloud Galaxy runs assembly/disassembly documents, and the downstream MySQL data warehouse and analytics systems need the sub-item details for cost accounting and inventory aggregation. Manual export is not realistic given the high frequency of sub-item line changes, and polling the Kingdee API too aggressively slows down the source system. We use the Qeasy integration platform to host this strategy: the source side pulls sub-items every 8 minutes, then writes to MySQL for downstream distribution.
Data Flow and Field Mapping
The flow is: Kingdee Cloud Galaxy → Qeasy integration platform (middleware) → MySQL. The source side calls Kingdee's executeBillQuery (POST, QUERY type), filtered by document number FBillNo and sub-item line FSubEntity_FDetailID. The target side writes in batches via batchexecute on MySQL, with the primary key id used for idempotency.
Key field mapping:
| Meaning | Kingdee Field | MySQL Field | Note |
|---|---|---|---|
| Sub-item entry ID | FEntity_FEntryID | FEntity_FEntryID | Injected via {{FSubEntity_FDetailID}} |
| Document No. | FBillNo | FBillNo | Unique per document |
| Document Type | FBillTypeID | FBillTypeID | Type code |
| Remark | FNote | FNote | Text |
| Stock Org Code | FStockOrgId.FNumber | FStockOrg_FNumber | Code under org object |
| Stock Org Name | FStockOrgId.FName | FStockOrg_FName | Display only |
The names
FSubEntity_FDetailIDandFEntity_FEntryIDare easy to mix up. Centralize this kind of mapping in Qeasy instead of scattering it across downstream scripts.
How to Configure in Qeasy
Inside the Qeasy integration platform, this strategy is essentially a "source query → target write" pipeline. Four configuration points matter:
- Source connector: Pick Kingdee Cloud Galaxy, configure auth for the public cloud tenant; choose the
executeBillQueryAPI and exposeFBillNoandFSubEntity_FDetailIDas injectable variables. KeepautoFillResponseon to avoid hand-building responses. - Target connector: Pick MySQL, set
apitobatchexecute,idCheck=true, and rely on the primary keyidfor idempotency to prevent duplicate writes. - Field mapping: Use Qeasy's mapping canvas to align fields one by one. For nested fields like
FStockOrgId.FNumber, the source connector auto-expands them. LeavebuildModeloff so real API calls are made. - Scheduling: Source
crontabis*/8 * * * *; target is shifted 5 minutes to3-59/8 * * * *, leaving a window for the source to finish querying and staging.
Implementation Steps
On customer sites we typically roll this strategy out in three phases:
- Phase 1: Incremental starting point. Cold start with the most recent 7 days of approved assembly/disassembly documents. Pull
FBillNoand sub-item lineFSubEntity_FDetailIDinto MySQL. In Qeasy, setnumbertoFBillNo,idtoFEntity_FEntryID, andidCheck=falseso the initial load can land without collision. - Phase 2: Full-volume trigger. After cold start, switch the source filter to "last modified time ≥ last sync time" and turn
idCheck=trueon the target side to deduplicate via the primary keyid. This is the common "incremental + full-volume dual-track" approach: keep the full-volume backfill channel while daily traffic runs incrementally. - Phase 3: Scheduling cadence. Source runs every 8 minutes via
*/8 * * * *; target writes on a shifted cadence via3-59/8 * * * *. After a week of observation, review source API latency and MySQL write delay before tightening the polling interval to 5 minutes.
Lessons Learned
- Wrong nesting in object-attribute fields. Missing or extra dots in
FStockOrgId.FNumbercause the source to return empty values. The reliable approach is to centralize nested fields in Qeasy's code-mapping module instead of letting each consumer re-parse them. - Idempotency check on during cold start. With
idCheck=trueon the first full-volume load, the empty target table triggers false collisions. KeepidCheckoff during cold start and only switch it on once the initial write completes. - Source and target on the same cadence. If the target side starts writing to MySQL before the source pull finishes, rows get dropped. The simplest and most effective fix is to offset the target
crontabby a few minutes. - Mixing header and body rows. Assembly/disassembly documents have both headers (
FBillNo,FBillTypeID) and body lines (FEntity_FEntryID,FNote). Writing them straight to the database after one API call tends to mis-attach body lines to headers. We use a "header and body phased" pattern: land the header table first, then write the child rows usingFBillNoas a foreign key, with the primary keyidon the MySQL side as the unique constraint. - Resume from
FBillNo. If an 8-minute round fails, Qeasy puts the currentFBillNolist into the retry queue. Do not write your own compensation scripts in parallel — they will fight the platform's dedup logic.
When to Use and When Not
Use it when: Kingdee Cloud Galaxy documents such as assembly/disassembly, transfers, or other in/out documents carry body sub-items that need to be incrementally landed in MySQL for downstream analytics or inventory aggregation. Do not use it when: sub-second real-time sync is required at the shop floor (8-minute polling is too slow), or when the Kingdee tenant does not have executeBillQuery permission.