Data Migration Strategies
Overview
- What you’ll learn:
- How to plan a data migration using a structured methodology — from assessment and mapping through transformation, loading, and validation
- How to use iDempiere’s Import Loader framework, SQL migration scripts, and ETL tools to move master and transactional data from legacy systems
- How to test migrations, plan cutovers, run parallel systems, and ensure data quality in the new iDempiere environment
- Prerequisites: Lessons 1-15 (understanding of iDempiere data model), SQL proficiency, familiarity with data analysis tools
- Estimated reading time: 25 minutes
Introduction
Data migration is simultaneously the most underestimated and most critical phase of any ERP implementation. Organizations frequently allocate months for requirements gathering and configuration, weeks for user acceptance testing, but then compress data migration into a frantic weekend before go-live. The result is predictable: missing records, incorrect balances, broken references, and users who lose trust in the new system from day one.
Successful data migration requires disciplined methodology, thorough planning, and — critically — multiple rehearsals before the actual cutover. This lesson provides a comprehensive framework for migrating data from legacy systems to iDempiere, covering every phase from initial assessment through post-migration validation.
Data Migration Methodology
A proven data migration follows a structured sequence of phases. Skipping or shortcutting any phase creates risk that compounds in later phases.
Phase 1: Assess
Before touching any data, understand what you are dealing with:
- Source system inventory: Document every data source — the legacy ERP database, spreadsheets, emails, paper records, and third-party systems. Many organizations are surprised by how much critical business data lives outside their primary ERP.
- Data volume analysis: Count records by entity type (customers, vendors, products, open orders, historical transactions). This drives technical decisions about migration approach and timing.
- Data quality assessment: Profile the source data for completeness (how many records have missing fields?), accuracy (do addresses validate? are tax IDs correctly formatted?), consistency (is the same customer entered multiple times with different names?), and currency (when was the data last updated?).
- Dependency mapping: Identify which data entities depend on others. For example, invoices reference business partners and products, so business partners and products must be migrated before invoices.
Phase 2: Plan
Based on the assessment, define the migration strategy:
- Scope decisions: Not all data needs to be migrated. Historical transactions older than a certain date may be archived rather than migrated. Inactive products, closed customers, and fully-paid invoices may be excluded. Define clear scope boundaries.
- Migration approach: Will you use iDempiere’s Import Loader (best for standard entities), direct SQL insertion (fastest for large volumes), ETL tools (best for complex transformations), or a combination?
- Sequence: Define the order of migration. A typical sequence is: (1) Chart of Accounts, (2) Tax configuration, (3) Business Partners, (4) Products and Price Lists, (5) Opening balances, (6) Open documents (pending orders, unpaid invoices).
- Timeline: Allocate sufficient time for at least three full migration rehearsals before the actual cutover.
Phase 3: Map
Create detailed data mapping documents that specify, for every target field in iDempiere, where the data comes from and how it is transformed:
| iDempiere Target | Source Field | Transformation | Default | Required |
|---|---|---|---|---|
| C_BPartner.Value | LEGACY.CUSTOMER.CUST_CODE | Trim, uppercase | — | Yes |
| C_BPartner.Name | LEGACY.CUSTOMER.CUST_NAME | Trim, proper case | — | Yes |
| C_BPartner.TaxID | LEGACY.CUSTOMER.TAX_NUM | Remove dashes/spaces | — | No |
| C_BPartner.IsCustomer | LEGACY.CUSTOMER.TYPE | ‘C’ or ‘B’ maps to Y | N | Yes |
| C_BPartner.C_BP_Group_ID | LEGACY.CUSTOMER.CATEGORY | Lookup mapping table | Standard | Yes |
Data mapping documents serve as the specification for your migration scripts and as the reference for validation testing. Keep them under version control and update them as mapping decisions change.
Phase 4: Cleanse
Clean the data before migration, not after. Common cleansing tasks include:
- Deduplication: Identify and merge duplicate records (e.g., the same customer entered as “ACME Corp”, “Acme Corporation”, and “ACME CORP.”). Use fuzzy matching algorithms and manual review.
- Standardization: Apply consistent formats to addresses (postal code validation, country code standardization), phone numbers (international format), and names (proper case, abbreviation expansion).
- Enrichment: Fill in missing data that iDempiere requires but the source system does not have (e.g., payment terms, price list assignments, accounting dimensions).
- Validation: Verify referential integrity in the source data — do all invoice references point to valid customers? Do all order lines reference valid products?
Phase 5: Transform and Load
Execute the actual data transformation and loading using one or more of the techniques described in the following sections.
Phase 6: Validate
After loading, systematically verify the migrated data against defined acceptance criteria (covered in detail in the post-migration validation section below).
iDempiere Import Loader Framework
iDempiere provides a built-in import mechanism based on staging tables (prefixed with I_). This is the recommended approach for standard entity migrations because it leverages iDempiere’s own validation logic and creates proper audit trails.
The I_ Tables Pattern
The import process follows a consistent pattern across all import types:
- Populate the import table: Insert records into the staging table (e.g.,
I_BPartner,I_Product,I_Invoice,I_GLJournal) via CSV upload, SQL INSERT, or ETL tool. The import table contains both the raw data fields and resolution fields (e.g., bothBPartner_ValueandC_BPartner_ID). - Run the Import process: Execute the corresponding Import process from the iDempiere menu. The process resolves lookups (matching text values to iDempiere IDs), validates data (mandatory fields, valid references), and flags errors. Records with errors are marked in the
I_ErrorMsgcolumn andI_IsImportedis set to ‘E’. - Review and fix errors: Query the import table for records with errors, fix the data, and re-run the import process. Iterate until all records are successfully imported.
- Verify in iDempiere: Open the corresponding iDempiere windows to spot-check that imported records appear correctly.
Available Import Tables
- I_BPartner: Business partners (customers, vendors), including addresses and contacts.
- I_Product: Products and items.
- I_Invoice: Vendor and customer invoices with line items.
- I_Order: Sales and purchase orders with line items.
- I_GLJournal: General ledger journal entries for opening balances.
- I_Payment: Payments and receipts.
- I_BankStatement: Bank statement lines.
- I_Inventory: Physical inventory counts for initial stock loading.
- I_ElementValue: Chart of accounts (account elements).
- I_ReportLine: Financial report line definitions.
CSV Import Process
The most common method for loading import tables is via CSV files:
- Prepare the CSV file with column headers matching the import table column names.
- In iDempiere, navigate to the Import File Loader window.
- Select the target import table, upload the CSV file, and map columns.
- Run the loader to populate the import table.
- Run the corresponding Import process to validate and create records.
-- Example: Directly loading I_BPartner via SQL (alternative to CSV upload)
INSERT INTO I_BPartner (
AD_Client_ID, AD_Org_ID, IsActive, Created, CreatedBy,
Updated, UpdatedBy,
Value, Name, Name2, TaxID,
IsCustomer, IsVendor,
GroupValue, -- Resolves to C_BP_Group_ID
I_IsImported, I_ErrorMsg
)
SELECT
1000000, 0, 'Y', now(), 100, now(), 100,
TRIM(cust_code),
TRIM(cust_name),
TRIM(cust_name2),
REGEXP_REPLACE(tax_num, '[^0-9A-Za-z]', '', 'g'),
CASE WHEN cust_type IN ('C','B') THEN 'Y' ELSE 'N' END,
CASE WHEN cust_type IN ('V','B') THEN 'Y' ELSE 'N' END,
'Standard',
'N', NULL
FROM legacy_staging.customers
WHERE cust_status = 'ACTIVE';
SQL-Based Migration Scripts
For large data volumes or complex transformations that exceed what the Import Loader can handle efficiently, direct SQL insertion into iDempiere’s core tables is an option. This approach is faster but riskier — it bypasses iDempiere’s application-level validation, so you must ensure data integrity yourself.
Key Principles for Direct SQL Migration
- Generate IDs correctly: Use iDempiere’s
AD_Sequencetable to obtain valid primary key values. Never hardcode IDs or use ad-hoc sequences that could conflict with iDempiere’s own sequence generation.
-- Function to get next ID from iDempiere sequence
CREATE OR REPLACE FUNCTION get_next_id(p_table_name VARCHAR)
RETURNS INTEGER AS $$
DECLARE
v_id INTEGER;
BEGIN
UPDATE AD_Sequence
SET CurrentNext = CurrentNext + IncrementNo
WHERE Name = p_table_name
AND IsTableID = 'Y'
RETURNING CurrentNext - IncrementNo INTO v_id;
RETURN v_id;
END;
$$ LANGUAGE plpgsql;
- Populate all mandatory columns: Every iDempiere table requires
AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy, and the primary key column. - Respect referential integrity: Verify that all foreign key references point to valid records. Run integrity checks after insertion.
- Disable triggers carefully: If you need to disable triggers for performance during bulk inserts, re-enable them immediately after and then run the validation logic that the triggers would have enforced.
- Wrap in transactions: Execute migration scripts within database transactions so you can roll back the entire batch if errors are detected.
Post-Insert Validation Queries
-- Check for orphaned foreign key references after migration
SELECT 'Missing BPartner' as issue, COUNT(*)
FROM C_Invoice i
WHERE i.C_BPartner_ID NOT IN (SELECT C_BPartner_ID FROM C_BPartner)
AND i.AD_Client_ID = 1000000
UNION ALL
SELECT 'Missing Product' as issue, COUNT(*)
FROM C_InvoiceLine il
WHERE il.M_Product_ID IS NOT NULL
AND il.M_Product_ID NOT IN (SELECT M_Product_ID FROM M_Product)
AND il.AD_Client_ID = 1000000
UNION ALL
SELECT 'Missing Account' as issue, COUNT(*)
FROM Fact_Acct fa
WHERE fa.Account_ID NOT IN (SELECT C_ElementValue_ID FROM C_ElementValue)
AND fa.AD_Client_ID = 1000000;
ETL Tools Overview
For complex migrations involving multiple source systems, heavy transformations, and ongoing data synchronization, dedicated ETL (Extract, Transform, Load) tools provide a more manageable approach than hand-written SQL scripts.
Pentaho Data Integration (Kettle)
Pentaho is particularly relevant for iDempiere because both projects share heritage in the Compiere/ADempiere ecosystem. Pentaho provides visual data pipeline design with drag-and-drop transformations. Key strengths include:
- Native JDBC connectivity to both source and target databases.
- Rich transformation steps (lookups, joins, aggregations, data cleansing, fuzzy matching).
- Reusable transformation templates — design once, parameterize for different entities.
- Built-in logging and error handling for each transformation step.
Talend Open Studio
Talend generates Java code from visual pipeline designs, providing both ease of design and high performance. It offers extensive connectors for databases, file formats, web services, and cloud platforms. The open-source Community Edition is sufficient for most migration projects.
Custom Python Scripts
For organizations without ETL tool expertise, well-structured Python scripts using libraries like pandas (for data transformation) and psycopg2 or SQLAlchemy (for database interaction) can be effective for smaller migrations:
# Example: Python-based data migration for Business Partners
import pandas as pd
import psycopg2
from psycopg2.extras import execute_batch
# Extract from legacy system
legacy_conn = psycopg2.connect(host="legacy-db", dbname="legacy_erp")
df = pd.read_sql("SELECT * FROM customers WHERE status = 'ACTIVE'", legacy_conn)
# Transform
df['Value'] = df['cust_code'].str.strip().str.upper()
df['Name'] = df['cust_name'].str.strip().str.title()
df['TaxID'] = df['tax_num'].str.replace(r'[^0-9A-Za-z]', '', regex=True)
df['IsCustomer'] = df['cust_type'].isin(['C', 'B']).map({True: 'Y', False: 'N'})
# Load into iDempiere import table
idempiere_conn = psycopg2.connect(host="idempiere-db", dbname="idempiere")
insert_sql = """
INSERT INTO I_BPartner (AD_Client_ID, AD_Org_ID, IsActive,
Created, CreatedBy, Updated, UpdatedBy,
Value, Name, TaxID, IsCustomer, GroupValue,
I_IsImported, I_ErrorMsg)
VALUES (1000000, 0, 'Y', now(), 100, now(), 100,
%(Value)s, %(Name)s, %(TaxID)s, %(IsCustomer)s, 'Standard',
'N', NULL)
"""
execute_batch(idempiere_conn.cursor(), insert_sql, df.to_dict('records'))
idempiere_conn.commit()
Migrating Master Data
Master data migration is the foundation upon which all transactional migration depends. Errors in master data cascade into every transaction that references them.
Chart of Accounts
The Chart of Accounts (CoA) defines the accounting structure and must be migrated first:
- Map the legacy account structure to iDempiere’s account element structure (
C_ElementValue). - Determine how the legacy account segments map to iDempiere’s accounting dimensions (Account, Organization, Business Partner, Product, Activity, Campaign, Project).
- Use the
I_ElementValueimport table or direct SQL to create the account elements. - Configure the default accounts in the Accounting Schema to reference the migrated chart of accounts.
Pay special attention to account types (Asset, Liability, Equity, Revenue, Expense) and summary vs. posting accounts. iDempiere requires correct account type assignments for financial statements to balance properly.
Business Partners
Business partners include customers, vendors, and employees. The migration must handle:
- The
C_BPartnerheader record (name, search key, tax ID, group, payment terms). - One or more
C_BPartner_Locationrecords (addresses) with properC_Locationrecords (country, region, city, postal code). - One or more
AD_Usercontact records linked to the business partner. - Customer-specific data (
C_BPartner.IsCustomer, credit limits, price lists). - Vendor-specific data (
C_BPartner.IsVendor, payment rules, purchase price lists). - Bank account information (
C_BP_BankAccount) for payment processing.
The I_BPartner import table handles most of this in a single import pass, creating the partner, location, and contact records together.
Products
Product migration includes:
- The
M_Productrecord (search key, name, UOM, product category, product type). - Price list entries (
M_ProductPrice) for each applicable price list version. - Bill of Materials (
PP_Product_BOMandPP_Product_BOMLine) for manufactured items. - Product attributes and attribute set instances for lot-tracked or serialized items.
- Replenishment rules and warehouse-specific configurations.
Migrating Transactional Data
Transactional migration is more complex than master data migration because it involves document state, accounting implications, and temporal consistency.
Opening Balances
The most common approach for financial cutover is to migrate opening balances as of a specific date rather than recreating every historical transaction:
- General Ledger balances: Create a GL Journal entry that debits and credits all balance sheet accounts to match the legacy trial balance as of the cutover date. Use the
I_GLJournalimport table. The journal should use a specific document type (e.g., “Opening Balance”) for easy identification. - Accounts Receivable sub-ledger: Import individual open (unpaid) customer invoices so that the AR aging report in iDempiere matches the legacy system. Each open invoice is imported via
I_Invoiceand completed to create the accounting entries. - Accounts Payable sub-ledger: Similarly, import open vendor invoices to establish the AP sub-ledger.
- Inventory: Use
I_Inventoryto load physical inventory counts, establishing opening stock quantities and values. - Bank balances: Create opening bank statement entries or GL journal entries to establish bank account balances.
Open Documents
Pending business documents that will continue to be active after cutover must be migrated:
- Open Sales Orders: Orders that have been placed but not yet fully shipped and invoiced. Import via
I_Orderor direct SQL, ensuring line quantities reflect only the outstanding (undelivered) amounts. - Open Purchase Orders: Orders placed with vendors where goods have not yet been fully received.
- Pending Shipments: Partially shipped orders that require additional shipments.
For each open document, carefully determine the correct document status (Drafted, In Progress, Completed) and ensure that quantity fields reflect the current state, not the original order quantities.
Historical Data Considerations
Decide how to handle historical data that will not be actively used in iDempiere but may be needed for reference:
- Full migration: Import all historical transactions. This provides complete reporting history in iDempiere but significantly increases migration complexity and time.
- Summary migration: Import monthly or quarterly summary GL journal entries for historical periods, providing period-level reporting without individual transaction detail.
- Archive access: Keep the legacy system available in read-only mode for historical lookups. This is often the most pragmatic approach for detailed historical data.
Migration Testing Strategies
Migration testing is not a single event — it is a series of rehearsals, each more complete and realistic than the last.
Rehearsal Approach
- Rehearsal 1 (Technical validation): Run the full migration against a test database. Verify that all scripts execute without errors, record counts match expectations, and foreign key relationships are valid. Focus on technical correctness, not business validation.
- Rehearsal 2 (Business validation): Run the migration again and have business users validate the results. Compare key reports (trial balance, aging reports, inventory valuation) between the legacy system and iDempiere. Fix data quality issues and mapping errors.
- Rehearsal 3 (Dress rehearsal): Simulate the actual cutover process end-to-end, including the data freeze in the legacy system, migration execution, validation, and go/no-go decision. Time everything. This rehearsal should be as close to the real cutover as possible.
Validation Checks
Build automated validation scripts that compare source and target data:
-- Record count comparison
SELECT 'Business Partners' as entity,
(SELECT COUNT(*) FROM legacy_staging.customers
WHERE cust_status = 'ACTIVE') as source_count,
(SELECT COUNT(*) FROM C_BPartner
WHERE AD_Client_ID = 1000000
AND IsActive = 'Y') as target_count;
-- Financial balance comparison
SELECT 'AR Balance' as entity,
(SELECT SUM(open_amount) FROM legacy_staging.open_invoices
WHERE doc_type = 'AR') as source_balance,
(SELECT SUM(OpenAmt) FROM RV_OpenItem
WHERE AD_Client_ID = 1000000
AND IsSOTrx = 'Y') as target_balance;
-- Inventory quantity comparison
SELECT 'Total Inventory Qty' as entity,
(SELECT SUM(qty_on_hand) FROM legacy_staging.inventory) as source_qty,
(SELECT SUM(QtyOnHand) FROM M_StorageOnHand
WHERE AD_Client_ID = 1000000) as target_qty;
Cutover Planning
The cutover is the critical moment when the organization switches from the legacy system to iDempiere. Meticulous planning and rehearsal are essential.
Cutover Steps
- Data freeze: Stop all data entry in the legacy system at a defined time (typically end of business on a Friday or end of a fiscal period).
- Final data extraction: Extract the latest data from the legacy system, including any transactions entered since the last rehearsal extraction.
- Migration execution: Run the migration scripts against the production iDempiere database. This should be highly automated based on the rehearsal experience.
- Validation: Execute the automated validation scripts and have designated business users perform spot checks of critical data.
- Go/No-Go decision: Based on validation results, decide whether to proceed with go-live or roll back.
- Go-live: Enable user access to iDempiere. The legacy system remains available in read-only mode for reference.
Parallel Running
For high-risk migrations, a parallel running period (typically 1-3 months) where transactions are entered in both the legacy system and iDempiere provides a safety net. Results are compared at the end of each period (daily, weekly, or monthly) to identify discrepancies. Parallel running is expensive (double data entry) but provides maximum confidence.
Rollback Plan
Always have a rollback plan. Before cutover, take a full backup of the iDempiere database. If the migration fails validation or critical issues are discovered post-go-live, you can restore the backup and continue operating on the legacy system while issues are resolved. Define clear rollback criteria and a decision deadline (e.g., “If validation is not complete by Sunday 6 PM, we roll back”).
Post-Migration Data Quality Monitoring
Data quality does not end at cutover. The first weeks and months of operation in iDempiere will reveal data issues that were not caught during migration testing.
- Daily reconciliation: During the first month, reconcile key financial figures between iDempiere reports and independent sources (bank statements, tax returns, legacy system read-only access).
- Data quality dashboards: Build SQL-based checks that run daily and flag anomalies — orphaned records, unexpected NULL values in mandatory fields, duplicate business partner entries, accounting imbalances.
- User feedback channel: Establish a clear process for users to report data issues. Treat data quality issues with the same urgency as software bugs during the initial stabilization period.
- Legacy system retirement: Keep the legacy system available in read-only mode for at least 6-12 months post-migration to support lookups of historical data that was not migrated.
Summary
Data migration is a discipline that requires equal parts technical skill and project management rigor. The key success factors are:
- Start early — data assessment and cleansing can begin months before the planned go-live.
- Use iDempiere’s Import Loader for standard entities; supplement with SQL and ETL for complex scenarios.
- Rehearse the full migration at least three times before the real cutover.
- Build automated validation scripts and compare source-to-target data systematically.
- Plan for rollback — hope is not a strategy.
- Monitor data quality actively in the weeks following migration.
In the next lesson, we will zoom out to the broader picture — how to build complete business solutions on iDempiere, from requirements gathering through go-live and beyond.
繁體中文翻譯
概述
- 學習內容:
- 如何使用結構化方法論規劃資料遷移 — 從評估和對應到轉換、載入和驗證
- 如何使用 iDempiere 的 Import Loader 框架、SQL 遷移腳本和 ETL 工具,將主資料和交易資料從舊系統遷移
- 如何測試遷移、規劃切換、運行平行系統,以及確保新 iDempiere 環境中的資料品質
- 先備知識:第 1-15 課(了解 iDempiere 資料模型)、SQL 精通、熟悉資料分析工具
- 預估閱讀時間:25 分鐘
簡介
資料遷移同時是任何 ERP 導入中最被低估和最關鍵的階段。組織經常為需求收集和設定分配數月時間、為使用者驗收測試分配數週時間,但隨後將資料遷移壓縮在上線前的一個緊張週末。結果是可預見的:缺失記錄、不正確的餘額、斷裂的參照,以及從第一天起就對新系統失去信任的使用者。
成功的資料遷移需要嚴謹的方法論、周密的規劃,以及——至關重要的——在實際切換之前進行多次演練。本課提供了從舊系統遷移資料到 iDempiere 的完整框架,涵蓋從初始評估到遷移後驗證的每個階段。
資料遷移方法論
經過驗證的資料遷移遵循結構化的階段順序。跳過或壓縮任何階段都會產生在後續階段中加劇的風險。
第 1 階段:評估
在處理任何資料之前,了解您面對的是什麼:
- 來源系統清查:記錄每一個資料來源 — 舊 ERP 資料庫、試算表、電子郵件、紙本記錄和第三方系統。許多組織會驚訝地發現有多少關鍵業務資料存在於主要 ERP 之外。
- 資料量分析:按實體類型(客戶、供應商、產品、未結訂單、歷史交易)統計記錄數量。這會影響有關遷移方法和時間的技術決策。
- 資料品質評估:分析來源資料的完整性(有多少記錄缺少欄位?)、準確性(地址是否有效?稅務識別碼格式是否正確?)、一致性(同一客戶是否以不同名稱被多次輸入?)和時效性(資料最後一次更新是什麼時候?)。
- 依賴關係對應:識別哪些資料實體依賴於其他實體。例如,發票參照業務夥伴和產品,因此業務夥伴和產品必須在發票之前遷移。
第 2 階段:規劃
根據評估結果,定義遷移策略:
- 範圍決策:並非所有資料都需要遷移。超過特定日期的歷史交易可以歸檔而非遷移。不活動的產品、已關閉的客戶和已全額付款的發票可以排除在外。定義明確的範圍界限。
- 遷移方法:您將使用 iDempiere 的 Import Loader(最適合標準實體)、直接 SQL 插入(大量資料最快)、ETL 工具(最適合複雜轉換)還是組合方法?
- 順序:定義遷移順序。典型的順序是:(1) 會計科目表、(2) 稅務設定、(3) 業務夥伴、(4) 產品和價目表、(5) 期初餘額、(6) 未結單據(待處理訂單、未付發票)。
- 時間表:分配足夠的時間,在實際切換之前至少進行三次完整的遷移演練。
第 3 階段:對應
建立詳細的資料對應文件,指定 iDempiere 中每個目標欄位的資料來源和轉換方式:
| iDempiere 目標 | 來源欄位 | 轉換 | 預設值 | 必填 |
|---|---|---|---|---|
| C_BPartner.Value | LEGACY.CUSTOMER.CUST_CODE | 修剪、轉大寫 | — | 是 |
| C_BPartner.Name | LEGACY.CUSTOMER.CUST_NAME | 修剪、首字母大寫 | — | 是 |
| C_BPartner.TaxID | LEGACY.CUSTOMER.TAX_NUM | 移除破折號/空格 | — | 否 |
| C_BPartner.IsCustomer | LEGACY.CUSTOMER.TYPE | ‘C’ 或 ‘B’ 對應至 Y | N | 是 |
| C_BPartner.C_BP_Group_ID | LEGACY.CUSTOMER.CATEGORY | 查找對應表 | Standard | 是 |
資料對應文件作為遷移腳本的規格說明和驗證測試的參考。將它們納入版本控制,並在對應決策變更時更新。
第 4 階段:清理
在遷移前清理資料,而非遷移後。常見的清理任務包括:
- 去重複:識別並合併重複記錄(例如,同一客戶分別以「ACME Corp」、「Acme Corporation」和「ACME CORP.」輸入)。使用模糊比對演算法和人工審查。
- 標準化:對地址(郵遞區號驗證、國家代碼標準化)、電話號碼(國際格式)和名稱(首字母大寫、縮寫展開)套用一致的格式。
- 補充:填入 iDempiere 需要但來源系統沒有的遺漏資料(例如付款條件、價目表指派、會計維度)。
- 驗證:驗證來源資料中的參照完整性 — 所有發票參照是否指向有效客戶?所有訂單明細是否參照有效產品?
第 5 階段:轉換和載入
使用以下章節所述的一種或多種技術執行實際的資料轉換和載入。
第 6 階段:驗證
載入後,根據定義的驗收標準系統化地驗證已遷移的資料(在下方的遷移後驗證章節中詳細介紹)。
iDempiere Import Loader 框架
iDempiere 提供基於暫存表(前綴為 I_)的內建匯入機制。這是標準實體遷移的建議方法,因為它利用 iDempiere 自身的驗證邏輯並建立適當的稽核軌跡。
I_ 表模式
匯入流程在所有匯入類型中遵循一致的模式:
- 填充匯入表:透過 CSV 上傳、SQL INSERT 或 ETL 工具將記錄插入暫存表(例如
I_BPartner、I_Product、I_Invoice、I_GLJournal)。匯入表包含原始資料欄位和解析欄位(例如BPartner_Value和C_BPartner_ID)。 - 執行匯入流程:從 iDempiere 選單執行相應的匯入流程。此流程解析查找值(將文字值比對到 iDempiere ID)、驗證資料(必填欄位、有效參照),並標記錯誤。有錯誤的記錄在
I_ErrorMsg欄位中標記,I_IsImported設為 ‘E’。 - 審查並修正錯誤:查詢匯入表中有錯誤的記錄、修正資料,並重新執行匯入流程。反覆執行直到所有記錄成功匯入。
- 在 iDempiere 中驗證:開啟相應的 iDempiere 視窗,抽查匯入的記錄是否正確顯示。
可用的匯入表
- I_BPartner:業務夥伴(客戶、供應商),包括地址和聯絡人。
- I_Product:產品和品項。
- I_Invoice:供應商和客戶發票及明細項目。
- I_Order:銷售和採購訂單及明細項目。
- I_GLJournal:用於期初餘額的總帳分錄。
- I_Payment:付款和收款。
- I_BankStatement:銀行對帳單明細。
- I_Inventory:用於初始庫存載入的實體盤點。
- I_ElementValue:會計科目表(科目元素)。
- I_ReportLine:財務報表行定義。
CSV 匯入流程
載入匯入表最常見的方法是透過 CSV 檔案:
- 準備欄位標題與匯入表欄位名稱相符的 CSV 檔案。
- 在 iDempiere 中,瀏覽至 Import File Loader 視窗。
- 選擇目標匯入表、上傳 CSV 檔案並對應欄位。
- 執行載入器以填充匯入表。
- 執行相應的匯入流程以驗證並建立記錄。
-- 範例:透過 SQL 直接載入 I_BPartner(CSV 上傳的替代方案)
INSERT INTO I_BPartner (
AD_Client_ID, AD_Org_ID, IsActive, Created, CreatedBy,
Updated, UpdatedBy,
Value, Name, Name2, TaxID,
IsCustomer, IsVendor,
GroupValue, -- 解析為 C_BP_Group_ID
I_IsImported, I_ErrorMsg
)
SELECT
1000000, 0, 'Y', now(), 100, now(), 100,
TRIM(cust_code),
TRIM(cust_name),
TRIM(cust_name2),
REGEXP_REPLACE(tax_num, '[^0-9A-Za-z]', '', 'g'),
CASE WHEN cust_type IN ('C','B') THEN 'Y' ELSE 'N' END,
CASE WHEN cust_type IN ('V','B') THEN 'Y' ELSE 'N' END,
'Standard',
'N', NULL
FROM legacy_staging.customers
WHERE cust_status = 'ACTIVE';
基於 SQL 的遷移腳本
對於大量資料或超出 Import Loader 能有效處理的複雜轉換,直接將 SQL 插入 iDempiere 的核心表是一種選擇。這種方法更快但風險更高 — 它繞過了 iDempiere 的應用層級驗證,因此您必須自行確保資料完整性。
直接 SQL 遷移的關鍵原則
- 正確生成 ID:使用 iDempiere 的
AD_Sequence表取得有效的主鍵值。永遠不要硬編碼 ID 或使用可能與 iDempiere 自身序列生成衝突的臨時序列。
-- 從 iDempiere 序列取得下一個 ID 的函式
CREATE OR REPLACE FUNCTION get_next_id(p_table_name VARCHAR)
RETURNS INTEGER AS $$
DECLARE
v_id INTEGER;
BEGIN
UPDATE AD_Sequence
SET CurrentNext = CurrentNext + IncrementNo
WHERE Name = p_table_name
AND IsTableID = 'Y'
RETURNING CurrentNext - IncrementNo INTO v_id;
RETURN v_id;
END;
$$ LANGUAGE plpgsql;
- 填充所有必填欄位:每個 iDempiere 表都需要
AD_Client_ID、AD_Org_ID、IsActive、Created、CreatedBy、Updated、UpdatedBy和主鍵欄位。 - 遵守參照完整性:驗證所有外鍵參照都指向有效記錄。在插入後執行完整性檢查。
- 謹慎停用觸發器:如果需要在批次插入期間停用觸發器以提升效能,請在完成後立即重新啟用,然後執行觸發器原本會強制的驗證邏輯。
- 使用交易包裝:在資料庫交易中執行遷移腳本,以便在偵測到錯誤時可以回滾整個批次。
插入後驗證查詢
-- 遷移後檢查孤立的外鍵參照
SELECT 'Missing BPartner' as issue, COUNT(*)
FROM C_Invoice i
WHERE i.C_BPartner_ID NOT IN (SELECT C_BPartner_ID FROM C_BPartner)
AND i.AD_Client_ID = 1000000
UNION ALL
SELECT 'Missing Product' as issue, COUNT(*)
FROM C_InvoiceLine il
WHERE il.M_Product_ID IS NOT NULL
AND il.M_Product_ID NOT IN (SELECT M_Product_ID FROM M_Product)
AND il.AD_Client_ID = 1000000
UNION ALL
SELECT 'Missing Account' as issue, COUNT(*)
FROM Fact_Acct fa
WHERE fa.Account_ID NOT IN (SELECT C_ElementValue_ID FROM C_ElementValue)
AND fa.AD_Client_ID = 1000000;
ETL 工具概述
對於涉及多個來源系統、大量轉換和持續資料同步的複雜遷移,專用的 ETL(擷取、轉換、載入)工具比手寫 SQL 腳本提供更易管理的方法。
Pentaho Data Integration (Kettle)
Pentaho 與 iDempiere 特別相關,因為兩個專案在 Compiere/ADempiere 生態系統中有共同的傳承。Pentaho 提供拖放式轉換的視覺化資料管線設計。主要優勢包括:
- 對來源和目標資料庫的原生 JDBC 連線。
- 豐富的轉換步驟(查找、連接、彙總、資料清理、模糊比對)。
- 可重用的轉換範本 — 設計一次,為不同實體參數化。
- 每個轉換步驟的內建日誌記錄和錯誤處理。
Talend Open Studio
Talend 從視覺化管線設計生成 Java 程式碼,同時提供設計便利性和高效能。它為資料庫、檔案格式、Web 服務和雲端平台提供廣泛的連接器。開源社群版本對大多數遷移專案已足夠。
自訂 Python 腳本
對於沒有 ETL 工具專業知識的組織,使用 pandas(用於資料轉換)和 psycopg2 或 SQLAlchemy(用於資料庫互動)等函式庫的結構良好的 Python 腳本對較小的遷移可能很有效:
# 範例:基於 Python 的業務夥伴資料遷移
import pandas as pd
import psycopg2
from psycopg2.extras import execute_batch
# 從舊系統擷取
legacy_conn = psycopg2.connect(host="legacy-db", dbname="legacy_erp")
df = pd.read_sql("SELECT * FROM customers WHERE status = 'ACTIVE'", legacy_conn)
# 轉換
df['Value'] = df['cust_code'].str.strip().str.upper()
df['Name'] = df['cust_name'].str.strip().str.title()
df['TaxID'] = df['tax_num'].str.replace(r'[^0-9A-Za-z]', '', regex=True)
df['IsCustomer'] = df['cust_type'].isin(['C', 'B']).map({True: 'Y', False: 'N'})
# 載入到 iDempiere 匯入表
idempiere_conn = psycopg2.connect(host="idempiere-db", dbname="idempiere")
insert_sql = """
INSERT INTO I_BPartner (AD_Client_ID, AD_Org_ID, IsActive,
Created, CreatedBy, Updated, UpdatedBy,
Value, Name, TaxID, IsCustomer, GroupValue,
I_IsImported, I_ErrorMsg)
VALUES (1000000, 0, 'Y', now(), 100, now(), 100,
%(Value)s, %(Name)s, %(TaxID)s, %(IsCustomer)s, 'Standard',
'N', NULL)
"""
execute_batch(idempiere_conn.cursor(), insert_sql, df.to_dict('records'))
idempiere_conn.commit()
遷移主資料
主資料遷移是所有交易遷移的基礎。主資料中的錯誤會級聯到引用它們的每筆交易。
會計科目表
會計科目表(CoA)定義了會計結構,必須首先遷移:
- 將舊帳戶結構對應到 iDempiere 的科目元素結構(
C_ElementValue)。 - 確定舊帳戶區段如何對應到 iDempiere 的會計維度(科目、組織、業務夥伴、產品、活動、行銷活動、專案)。
- 使用
I_ElementValue匯入表或直接 SQL 建立科目元素。 - 設定會計模式中的預設科目以參照遷移的會計科目表。
特別注意帳戶類型(資產、負債、權益、收入、費用)以及彙總科目與過帳科目的區分。iDempiere 需要正確的帳戶類型指派才能使財務報表正確平衡。
業務夥伴
業務夥伴包括客戶、供應商和員工。遷移必須處理:
C_BPartner表頭記錄(名稱、搜尋鍵、稅務識別碼、群組、付款條件)。- 一個或多個
C_BPartner_Location記錄(地址),包含適當的C_Location記錄(國家、地區、城市、郵遞區號)。 - 一個或多個連結到業務夥伴的
AD_User聯絡人記錄。 - 客戶特定資料(
C_BPartner.IsCustomer、信用額度、價目表)。 - 供應商特定資料(
C_BPartner.IsVendor、付款規則、採購價目表)。 - 用於付款處理的銀行帳戶資訊(
C_BP_BankAccount)。
I_BPartner 匯入表在單次匯入中處理大部分內容,同時建立夥伴、地點和聯絡人記錄。
產品
產品遷移包括:
M_Product記錄(搜尋鍵、名稱、計量單位、產品類別、產品類型)。- 每個適用價目表版本的價格清單項目(
M_ProductPrice)。 - 製造品項的物料清單(
PP_Product_BOM和PP_Product_BOMLine)。 - 批次追蹤或序號追蹤品項的產品屬性和屬性集實例。
- 補貨規則和倉庫特定設定。
遷移交易資料
交易遷移比主資料遷移更為複雜,因為它涉及單據狀態、會計影響和時間一致性。
期初餘額
財務切換最常見的方法是遷移截至特定日期的期初餘額,而非重建每筆歷史交易:
- 總帳餘額:建立一筆總帳分錄,借貸所有資產負債表科目以匹配切換日期時舊系統的試算表。使用
I_GLJournal匯入表。該分錄應使用特定的單據類型(例如「期初餘額」)以便於識別。 - 應收帳款明細帳:匯入個別未結(未付)客戶發票,使 iDempiere 中的應收帳款帳齡報表與舊系統一致。每張未結發票透過
I_Invoice匯入並完成以建立會計分錄。 - 應付帳款明細帳:同樣地,匯入未結供應商發票以建立應付帳款明細帳。
- 庫存:使用
I_Inventory載入實體盤點,建立期初庫存數量和金額。 - 銀行餘額:建立期初銀行對帳單分錄或總帳分錄以建立銀行帳戶餘額。
未結單據
在切換後仍然活動的待處理業務單據必須遷移:
- 未結銷售訂單:已下單但尚未完全出貨和開立發票的訂單。透過
I_Order或直接 SQL 匯入,確保明細數量僅反映未完成(未交貨)的金額。 - 未結採購訂單:已向供應商下單但貨物尚未完全收到的訂單。
- 待處理出貨:需要額外出貨的部分出貨訂單。
對於每個未結單據,仔細確定正確的單據狀態(草稿、進行中、已完成),並確保數量欄位反映當前狀態,而非原始訂單數量。
歷史資料考量
決定如何處理不會在 iDempiere 中主動使用但可能需要查閱的歷史資料:
- 完整遷移:匯入所有歷史交易。這在 iDempiere 中提供完整的報表歷史,但大幅增加遷移的複雜度和時間。
- 摘要遷移:匯入歷史期間的月度或季度摘要總帳分錄,提供期間層級的報表而無需個別交易明細。
- 歸檔存取:將舊系統以唯讀模式保持可用,以供歷史資料查閱。這通常是處理詳細歷史資料最務實的方法。
遷移測試策略
遷移測試不是單次事件 — 它是一系列演練,每次比上一次更完整和真實。
演練方法
- 演練 1(技術驗證):在測試資料庫上執行完整遷移。驗證所有腳本無錯誤地執行、記錄數量符合預期,以及外鍵關係有效。專注於技術正確性,而非業務驗證。
- 演練 2(業務驗證):再次執行遷移,由業務使用者驗證結果。比較舊系統和 iDempiere 之間的關鍵報表(試算表、帳齡報表、庫存估值)。修正資料品質問題和對應錯誤。
- 演練 3(正式演練):端到端模擬實際切換過程,包括舊系統中的資料凍結、遷移執行、驗證和決定進行/不進行。記錄所有時間。此演練應盡可能接近實際切換。
驗證檢查
建立自動化驗證腳本,比較來源和目標資料:
-- 記錄數量比較
SELECT 'Business Partners' as entity,
(SELECT COUNT(*) FROM legacy_staging.customers
WHERE cust_status = 'ACTIVE') as source_count,
(SELECT COUNT(*) FROM C_BPartner
WHERE AD_Client_ID = 1000000
AND IsActive = 'Y') as target_count;
-- 財務餘額比較
SELECT 'AR Balance' as entity,
(SELECT SUM(open_amount) FROM legacy_staging.open_invoices
WHERE doc_type = 'AR') as source_balance,
(SELECT SUM(OpenAmt) FROM RV_OpenItem
WHERE AD_Client_ID = 1000000
AND IsSOTrx = 'Y') as target_balance;
-- 庫存數量比較
SELECT 'Total Inventory Qty' as entity,
(SELECT SUM(qty_on_hand) FROM legacy_staging.inventory) as source_qty,
(SELECT SUM(QtyOnHand) FROM M_StorageOnHand
WHERE AD_Client_ID = 1000000) as target_qty;
切換規劃
切換是組織從舊系統切換到 iDempiere 的關鍵時刻。周密的規劃和演練至關重要。
切換步驟
- 資料凍結:在定義的時間(通常是週五下班時或會計期間結束時)停止舊系統中的所有資料輸入。
- 最終資料擷取:從舊系統擷取最新資料,包括自上次演練擷取以來輸入的任何交易。
- 遷移執行:在生產環境的 iDempiere 資料庫上執行遷移腳本。根據演練經驗,這應該是高度自動化的。
- 驗證:執行自動化驗證腳本,並由指定的業務使用者對關鍵資料進行抽查。
- 決定進行/不進行:根據驗證結果,決定是繼續上線還是回滾。
- 上線:啟用使用者對 iDempiere 的存取。舊系統以唯讀模式保持可用以供參考。
平行運行
對於高風險遷移,平行運行期間(通常為 1-3 個月)在舊系統和 iDempiere 中同時輸入交易提供了安全網。在每個期間結束時(每日、每週或每月)比較結果以識別差異。平行運行成本高昂(雙重資料輸入),但提供最高的信心。
回滾計劃
務必準備回滾計劃。在切換前,對 iDempiere 資料庫進行完整備份。如果遷移未通過驗證或在上線後發現關鍵問題,您可以恢復備份並在問題解決期間繼續在舊系統上運作。定義明確的回滾標準和決策截止時間(例如「如果驗證在週日下午 6 點前未完成,我們將回滾」)。
遷移後資料品質監控
資料品質不會在切換時結束。在 iDempiere 中運作的前幾週和幾個月會揭示遷移測試中未發現的資料問題。
- 每日對帳:在第一個月期間,將 iDempiere 報表中的關鍵財務數據與獨立來源(銀行對帳單、稅務申報、舊系統唯讀存取)進行核對。
- 資料品質儀表板:建立每日執行的 SQL 檢查,標記異常 — 孤立記錄、必填欄位中的意外 NULL 值、重複的業務夥伴項目、會計不平衡。
- 使用者回饋管道:建立明確的流程讓使用者報告資料問題。在初始穩定期間,以與軟體錯誤相同的緊急程度處理資料品質問題。
- 舊系統退役:在遷移後至少 6-12 個月內將舊系統保持唯讀模式可用,以支援查閱未遷移的歷史資料。
總結
資料遷移是一門需要技術技能和專案管理嚴謹度的學科。關鍵成功因素是:
- 提早開始 — 資料評估和清理可以在計劃上線前數月開始。
- 對標準實體使用 iDempiere 的 Import Loader;對複雜場景使用 SQL 和 ETL 補充。
- 在真正切換前至少演練完整遷移三次。
- 建立自動化驗證腳本,系統化地比較來源與目標資料。
- 為回滾做好準備 — 期望不是策略。
- 在遷移後的數週內積極監控資料品質。
在下一課中,我們將放大到更宏觀的畫面 — 如何在 iDempiere 上建構完整的商業解決方案,從需求收集到上線及後續。
日本語翻訳
概要
- 学習内容:
- 構造化された方法論を使用してデータ移行を計画する方法 — アセスメントとマッピングから変換、ロード、検証まで
- iDempiere の Import Loader フレームワーク、SQL 移行スクリプト、ETL ツールを使用して、レガシーシステムからマスターデータとトランザクションデータを移行する方法
- 移行のテスト、カットオーバーの計画、並行システムの運用、新しい iDempiere 環境でのデータ品質の確保方法
- 前提知識:レッスン 1〜15(iDempiere データモデルの理解)、SQL の習熟、データ分析ツールの知識
- 推定読了時間:25 分
はじめに
データ移行は、あらゆる ERP 導入において最も過小評価されると同時に最も重要なフェーズです。組織は要件収集と設定に数か月、ユーザー受入テストに数週間を割り当てることが多いですが、データ移行は本番稼働前の慌ただしい週末に圧縮されます。結果は予測可能です:レコードの欠落、不正確な残高、壊れた参照、そして初日から新システムへの信頼を失うユーザーです。
成功するデータ移行には、規律ある方法論、綿密な計画、そして — 極めて重要なことに — 実際のカットオーバー前の複数回のリハーサルが必要です。このレッスンでは、レガシーシステムから iDempiere へのデータ移行のための包括的なフレームワークを提供し、初期アセスメントから移行後の検証までのすべてのフェーズをカバーします。
データ移行方法論
実績のあるデータ移行は、構造化されたフェーズのシーケンスに従います。いずれかのフェーズをスキップまたは短縮すると、後続のフェーズで増大するリスクが生じます。
フェーズ 1:アセスメント
データに触れる前に、何を扱っているかを理解します:
- ソースシステムのインベントリ:すべてのデータソースを文書化します — レガシー ERP データベース、スプレッドシート、メール、紙の記録、サードパーティシステム。多くの組織は、主要な ERP の外にどれだけ多くの重要なビジネスデータが存在するかに驚きます。
- データ量分析:エンティティタイプ別にレコード数を集計します(顧客、仕入先、製品、未決注文、過去の取引)。これにより、移行アプローチとタイミングに関する技術的な意思決定が左右されます。
- データ品質アセスメント:ソースデータの完全性(欠落フィールドのあるレコードはいくつか?)、正確性(住所は有効か?税務 ID の形式は正しいか?)、一貫性(同じ顧客が異なる名前で複数回入力されていないか?)、および鮮度(データが最後に更新されたのはいつか?)をプロファイリングします。
- 依存関係マッピング:どのデータエンティティが他に依存しているかを特定します。例えば、請求書はビジネスパートナーと製品を参照するため、ビジネスパートナーと製品は請求書より先に移行する必要があります。
フェーズ 2:計画
アセスメントに基づいて、移行戦略を定義します:
- スコープの決定:すべてのデータを移行する必要はありません。特定の日付より古い過去の取引は、移行ではなくアーカイブできます。非アクティブな製品、クローズされた顧客、全額支払済みの請求書は除外できます。明確なスコープ境界を定義します。
- 移行アプローチ:iDempiere の Import Loader(標準エンティティに最適)、直接 SQL 挿入(大量データに最速)、ETL ツール(複雑な変換に最適)、またはこれらの組み合わせを使用しますか?
- 順序:移行の順序を定義します。典型的な順序は:(1) 勘定科目表、(2) 税設定、(3) ビジネスパートナー、(4) 製品と価格リスト、(5) 期首残高、(6) 未決伝票(保留中の注文、未払請求書)です。
- タイムライン:実際のカットオーバー前に少なくとも 3 回の完全な移行リハーサルのための十分な時間を確保します。
フェーズ 3:マッピング
iDempiere のすべてのターゲットフィールドについて、データの取得元と変換方法を指定する詳細なデータマッピングドキュメントを作成します:
| iDempiere ターゲット | ソースフィールド | 変換 | デフォルト | 必須 |
|---|---|---|---|---|
| C_BPartner.Value | LEGACY.CUSTOMER.CUST_CODE | トリム、大文字化 | — | はい |
| C_BPartner.Name | LEGACY.CUSTOMER.CUST_NAME | トリム、先頭大文字 | — | はい |
| C_BPartner.TaxID | LEGACY.CUSTOMER.TAX_NUM | ダッシュ/スペース除去 | — | いいえ |
| C_BPartner.IsCustomer | LEGACY.CUSTOMER.TYPE | ‘C’ または ‘B’ を Y に | N | はい |
| C_BPartner.C_BP_Group_ID | LEGACY.CUSTOMER.CATEGORY | マッピングテーブル参照 | Standard | はい |
データマッピングドキュメントは、移行スクリプトの仕様書および検証テストの参照として機能します。バージョン管理下に置き、マッピングの決定が変更されたら更新します。
フェーズ 4:クレンジング
移行前にデータをクレンジングします(移行後ではなく)。一般的なクレンジングタスクには以下が含まれます:
- 重複排除:重複レコードを特定してマージします(例:同じ顧客が「ACME Corp」「Acme Corporation」「ACME CORP.」として入力されている)。ファジーマッチングアルゴリズムと手動レビューを使用します。
- 標準化:住所(郵便番号の検証、国コードの標準化)、電話番号(国際形式)、名前(先頭大文字、略称の展開)に一貫した形式を適用します。
- エンリッチメント:iDempiere が必要とするがソースシステムにないデータを補完します(例:支払条件、価格リストの割り当て、会計ディメンション)。
- 検証:ソースデータの参照整合性を検証します — すべての請求書参照は有効な顧客を指していますか?すべての注文明細は有効な製品を参照していますか?
フェーズ 5:変換とロード
以下のセクションで説明する 1 つ以上の手法を使用して、実際のデータ変換とロードを実行します。
フェーズ 6:検証
ロード後、定義された受入基準に対して移行データを体系的に検証します(移行後の検証セクションで詳述)。
iDempiere Import Loader フレームワーク
iDempiere は、ステージングテーブル(I_ プレフィックス)に基づく組み込みインポートメカニズムを提供します。これは標準エンティティの移行に推奨されるアプローチです。iDempiere 自身の検証ロジックを活用し、適切な監査証跡を作成するためです。
I_ テーブルパターン
インポートプロセスは、すべてのインポートタイプで一貫したパターンに従います:
- インポートテーブルへの入力:CSV アップロード、SQL INSERT、または ETL ツールを通じて、ステージングテーブル(例:
I_BPartner、I_Product、I_Invoice、I_GLJournal)にレコードを挿入します。インポートテーブルには、生データフィールドと解決フィールド(例:BPartner_ValueとC_BPartner_IDの両方)が含まれます。 - インポートプロセスの実行:iDempiere メニューから対応するインポートプロセスを実行します。プロセスはルックアップを解決し(テキスト値を iDempiere ID にマッチング)、データを検証し(必須フィールド、有効な参照)、エラーをフラグします。エラーのあるレコードは
I_ErrorMsgカラムにマークされ、I_IsImportedは ‘E’ に設定されます。 - エラーのレビューと修正:エラーのあるレコードをインポートテーブルで照会し、データを修正し、インポートプロセスを再実行します。すべてのレコードが正常にインポートされるまで繰り返します。
- iDempiere での確認:対応する iDempiere ウィンドウを開いて、インポートされたレコードが正しく表示されることをスポットチェックします。
利用可能なインポートテーブル
- I_BPartner:ビジネスパートナー(顧客、仕入先)、住所と連絡先を含みます。
- I_Product:製品とアイテムです。
- I_Invoice:仕入先と顧客の請求書と明細項目です。
- I_Order:販売注文と購買注文と明細項目です。
- I_GLJournal:期首残高用の総勘定元帳仕訳です。
- I_Payment:支払と入金です。
- I_BankStatement:銀行取引明細行です。
- I_Inventory:初期在庫ロード用の実地棚卸カウントです。
- I_ElementValue:勘定科目表(勘定科目要素)です。
- I_ReportLine:財務レポート行の定義です。
CSV インポートプロセス
インポートテーブルをロードする最も一般的な方法は CSV ファイルです:
- インポートテーブルのカラム名に一致するカラムヘッダーを持つ CSV ファイルを準備します。
- iDempiere で Import File Loader ウィンドウに移動します。
- ターゲットインポートテーブルを選択し、CSV ファイルをアップロードしてカラムをマッピングします。
- ローダーを実行してインポートテーブルにデータを投入します。
- 対応するインポートプロセスを実行してレコードを検証・作成します。
-- 例:SQL による I_BPartner の直接ロード(CSV アップロードの代替)
INSERT INTO I_BPartner (
AD_Client_ID, AD_Org_ID, IsActive, Created, CreatedBy,
Updated, UpdatedBy,
Value, Name, Name2, TaxID,
IsCustomer, IsVendor,
GroupValue, -- C_BP_Group_ID に解決
I_IsImported, I_ErrorMsg
)
SELECT
1000000, 0, 'Y', now(), 100, now(), 100,
TRIM(cust_code),
TRIM(cust_name),
TRIM(cust_name2),
REGEXP_REPLACE(tax_num, '[^0-9A-Za-z]', '', 'g'),
CASE WHEN cust_type IN ('C','B') THEN 'Y' ELSE 'N' END,
CASE WHEN cust_type IN ('V','B') THEN 'Y' ELSE 'N' END,
'Standard',
'N', NULL
FROM legacy_staging.customers
WHERE cust_status = 'ACTIVE';
SQL ベースの移行スクリプト
Import Loader では効率的に処理できない大量データや複雑な変換の場合、iDempiere のコアテーブルへの直接 SQL 挿入が選択肢となります。このアプローチはより高速ですがリスクも高く — iDempiere のアプリケーションレベルの検証をバイパスするため、データ整合性は自分で確保する必要があります。
直接 SQL 移行の主要原則
- ID の正しい生成:iDempiere の
AD_Sequenceテーブルを使用して有効な主キー値を取得します。ID をハードコードしたり、iDempiere 自身のシーケンス生成と競合する可能性のあるアドホックシーケンスを使用したりしないでください。
-- iDempiere シーケンスから次の ID を取得する関数
CREATE OR REPLACE FUNCTION get_next_id(p_table_name VARCHAR)
RETURNS INTEGER AS $$
DECLARE
v_id INTEGER;
BEGIN
UPDATE AD_Sequence
SET CurrentNext = CurrentNext + IncrementNo
WHERE Name = p_table_name
AND IsTableID = 'Y'
RETURNING CurrentNext - IncrementNo INTO v_id;
RETURN v_id;
END;
$$ LANGUAGE plpgsql;
- すべての必須カラムの入力:すべての iDempiere テーブルには
AD_Client_ID、AD_Org_ID、IsActive、Created、CreatedBy、Updated、UpdatedBy、および主キーカラムが必要です。 - 参照整合性の遵守:すべての外部キー参照が有効なレコードを指していることを確認します。挿入後に整合性チェックを実行します。
- トリガーの慎重な無効化:バルク挿入中にパフォーマンスのためにトリガーを無効にする必要がある場合は、完了後すぐに再有効化し、トリガーが適用するはずだった検証ロジックを実行します。
- トランザクションでのラップ:データベーストランザクション内で移行スクリプトを実行し、エラーが検出された場合にバッチ全体をロールバックできるようにします。
挿入後の検証クエリ
-- 移行後の孤立外部キー参照のチェック
SELECT 'Missing BPartner' as issue, COUNT(*)
FROM C_Invoice i
WHERE i.C_BPartner_ID NOT IN (SELECT C_BPartner_ID FROM C_BPartner)
AND i.AD_Client_ID = 1000000
UNION ALL
SELECT 'Missing Product' as issue, COUNT(*)
FROM C_InvoiceLine il
WHERE il.M_Product_ID IS NOT NULL
AND il.M_Product_ID NOT IN (SELECT M_Product_ID FROM M_Product)
AND il.AD_Client_ID = 1000000
UNION ALL
SELECT 'Missing Account' as issue, COUNT(*)
FROM Fact_Acct fa
WHERE fa.Account_ID NOT IN (SELECT C_ElementValue_ID FROM C_ElementValue)
AND fa.AD_Client_ID = 1000000;
ETL ツールの概要
複数のソースシステム、大規模な変換、継続的なデータ同期を伴う複雑な移行の場合、専用の ETL(Extract、Transform、Load)ツールは、手書きの SQL スクリプトよりも管理しやすいアプローチを提供します。
Pentaho Data Integration (Kettle)
Pentaho は iDempiere と特に関連性が高く、両プロジェクトは Compiere/ADempiere エコシステムに共通のルーツを持っています。Pentaho はドラッグアンドドロップの変換による視覚的なデータパイプライン設計を提供します。主な強みは以下の通りです:
- ソースとターゲットの両方のデータベースへのネイティブ JDBC 接続。
- 豊富な変換ステップ(ルックアップ、結合、集計、データクレンジング、ファジーマッチング)。
- 再利用可能な変換テンプレート — 一度設計し、異なるエンティティ用にパラメータ化。
- 各変換ステップの組み込みロギングとエラー処理。
Talend Open Studio
Talend は視覚的なパイプライン設計から Java コードを生成し、設計の容易さと高いパフォーマンスの両方を提供します。データベース、ファイル形式、Web サービス、クラウドプラットフォーム向けの広範なコネクタを提供します。オープンソースの Community Edition はほとんどの移行プロジェクトに十分です。
カスタム Python スクリプト
ETL ツールの専門知識がない組織では、pandas(データ変換用)と psycopg2 または SQLAlchemy(データベース操作用)などのライブラリを使用した構造化された Python スクリプトが、小規模な移行に効果的です:
# 例:Python ベースのビジネスパートナーデータ移行
import pandas as pd
import psycopg2
from psycopg2.extras import execute_batch
# レガシーシステムからの抽出
legacy_conn = psycopg2.connect(host="legacy-db", dbname="legacy_erp")
df = pd.read_sql("SELECT * FROM customers WHERE status = 'ACTIVE'", legacy_conn)
# 変換
df['Value'] = df['cust_code'].str.strip().str.upper()
df['Name'] = df['cust_name'].str.strip().str.title()
df['TaxID'] = df['tax_num'].str.replace(r'[^0-9A-Za-z]', '', regex=True)
df['IsCustomer'] = df['cust_type'].isin(['C', 'B']).map({True: 'Y', False: 'N'})
# iDempiere インポートテーブルへのロード
idempiere_conn = psycopg2.connect(host="idempiere-db", dbname="idempiere")
insert_sql = """
INSERT INTO I_BPartner (AD_Client_ID, AD_Org_ID, IsActive,
Created, CreatedBy, Updated, UpdatedBy,
Value, Name, TaxID, IsCustomer, GroupValue,
I_IsImported, I_ErrorMsg)
VALUES (1000000, 0, 'Y', now(), 100, now(), 100,
%(Value)s, %(Name)s, %(TaxID)s, %(IsCustomer)s, 'Standard',
'N', NULL)
"""
execute_batch(idempiere_conn.cursor(), insert_sql, df.to_dict('records'))
idempiere_conn.commit()
マスターデータの移行
マスターデータの移行は、すべてのトランザクション移行の基盤です。マスターデータのエラーは、それらを参照するすべてのトランザクションに連鎖します。
勘定科目表
勘定科目表(CoA)は会計構造を定義し、最初に移行する必要があります:
- レガシーの勘定科目構造を iDempiere の勘定科目要素構造(
C_ElementValue)にマッピングします。 - レガシーの勘定セグメントが iDempiere の会計ディメンション(勘定科目、組織、ビジネスパートナー、製品、活動、キャンペーン、プロジェクト)にどのようにマッピングされるかを決定します。
I_ElementValueインポートテーブルまたは直接 SQL を使用して勘定科目要素を作成します。- 会計スキーマのデフォルト勘定科目を移行された勘定科目表を参照するように設定します。
勘定科目タイプ(資産、負債、資本、収益、費用)および集計勘定科目と転記勘定科目の区別に特に注意してください。iDempiere が財務諸表を正しく均衡させるには、正しい勘定科目タイプの割り当てが必要です。
ビジネスパートナー
ビジネスパートナーには顧客、仕入先、従業員が含まれます。移行では以下を処理する必要があります:
C_BPartnerヘッダーレコード(名前、検索キー、税務 ID、グループ、支払条件)。- 適切な
C_Locationレコード(国、地域、市区町村、郵便番号)を持つ 1 つ以上のC_BPartner_Locationレコード(住所)。 - ビジネスパートナーにリンクされた 1 つ以上の
AD_User連絡先レコード。 - 顧客固有のデータ(
C_BPartner.IsCustomer、与信限度額、価格リスト)。 - 仕入先固有のデータ(
C_BPartner.IsVendor、支払ルール、購買価格リスト)。 - 支払処理用の銀行口座情報(
C_BP_BankAccount)。
I_BPartner インポートテーブルは、パートナー、住所、連絡先のレコードを 1 回のインポートパスでまとめて作成し、これらの大部分を処理します。
製品
製品の移行には以下が含まれます:
M_Productレコード(検索キー、名前、単位、製品カテゴリ、製品タイプ)。- 各適用可能な価格リストバージョンの価格リストエントリ(
M_ProductPrice)。 - 製造品目の部品表(
PP_Product_BOMおよびPP_Product_BOMLine)。 - ロット追跡またはシリアル追跡品目の製品属性と属性セットインスタンス。
- 補充ルールと倉庫固有の設定。
トランザクションデータの移行
トランザクションの移行は、伝票のステータス、会計上の影響、時間的整合性を伴うため、マスターデータの移行よりも複雑です。
期首残高
財務カットオーバーの最も一般的なアプローチは、過去のすべてのトランザクションを再作成するのではなく、特定の日付時点の期首残高を移行することです:
- 総勘定元帳残高:カットオーバー日時点でレガシーの試算表と一致するように、すべての貸借対照表勘定科目を借方・貸方に仕訳する GL 仕訳を作成します。
I_GLJournalインポートテーブルを使用します。この仕訳は識別しやすいように特定の伝票タイプ(例:「期首残高」)を使用する必要があります。 - 売掛金補助元帳:個別の未決(未払)顧客請求書をインポートし、iDempiere の AR 年齢表がレガシーシステムと一致するようにします。各未決請求書は
I_Invoiceでインポートし、完了して会計仕訳を作成します。 - 買掛金補助元帳:同様に、未決の仕入先請求書をインポートして AP 補助元帳を確立します。
- 在庫:
I_Inventoryを使用して実地棚卸カウントをロードし、期首在庫数量と金額を確立します。 - 銀行残高:期首の銀行取引明細エントリまたは GL 仕訳を作成して銀行口座残高を確立します。
未決伝票
カットオーバー後も引き続きアクティブな保留中のビジネス伝票は移行する必要があります:
- 未決販売注文:受注済みだがまだ完全に出荷・請求されていない注文。
I_Orderまたは直接 SQL でインポートし、明細数量が未処理(未出荷)分のみを反映するようにします。 - 未決購買注文:仕入先に発注済みだが商品がまだ完全に受領されていない注文。
- 保留中の出荷:追加出荷が必要な一部出荷済みの注文。
各未決伝票について、正しい伝票ステータス(ドラフト、処理中、完了)を慎重に決定し、数量フィールドが元の注文数量ではなく現在の状態を反映するようにします。
過去データの考慮事項
iDempiere でアクティブに使用されないが参照として必要になる可能性のある過去データの扱いを決定します:
- 完全移行:すべての過去のトランザクションをインポートします。iDempiere で完全なレポート履歴を提供しますが、移行の複雑さと時間が大幅に増加します。
- サマリー移行:過去の期間の月次または四半期サマリー GL 仕訳をインポートし、個別のトランザクション明細なしで期間レベルのレポートを提供します。
- アーカイブアクセス:レガシーシステムを読み取り専用モードで利用可能な状態に保ち、過去データの検索に使用します。詳細な過去データに対しては、これが最も実用的なアプローチであることが多いです。
移行テスト戦略
移行テストは単一のイベントではありません — 前回よりも完全でリアルなリハーサルの連続です。
リハーサルアプローチ
- リハーサル 1(技術検証):テストデータベースに対して完全な移行を実行します。すべてのスクリプトがエラーなく実行され、レコード数が期待値と一致し、外部キー関係が有効であることを確認します。ビジネス検証ではなく技術的な正確性に焦点を当てます。
- リハーサル 2(ビジネス検証):移行を再度実行し、ビジネスユーザーに結果を検証してもらいます。レガシーシステムと iDempiere 間の主要レポート(試算表、年齢表、在庫評価)を比較します。データ品質の問題とマッピングエラーを修正します。
- リハーサル 3(ドレスリハーサル):レガシーシステムでのデータ凍結、移行実行、検証、Go/No-Go 判断を含む実際のカットオーバープロセスをエンドツーエンドでシミュレートします。すべてのタイミングを計測します。このリハーサルは実際のカットオーバーにできるだけ近づける必要があります。
検証チェック
ソースとターゲットのデータを比較する自動検証スクリプトを構築します:
-- レコード数の比較
SELECT 'Business Partners' as entity,
(SELECT COUNT(*) FROM legacy_staging.customers
WHERE cust_status = 'ACTIVE') as source_count,
(SELECT COUNT(*) FROM C_BPartner
WHERE AD_Client_ID = 1000000
AND IsActive = 'Y') as target_count;
-- 財務残高の比較
SELECT 'AR Balance' as entity,
(SELECT SUM(open_amount) FROM legacy_staging.open_invoices
WHERE doc_type = 'AR') as source_balance,
(SELECT SUM(OpenAmt) FROM RV_OpenItem
WHERE AD_Client_ID = 1000000
AND IsSOTrx = 'Y') as target_balance;
-- 在庫数量の比較
SELECT 'Total Inventory Qty' as entity,
(SELECT SUM(qty_on_hand) FROM legacy_staging.inventory) as source_qty,
(SELECT SUM(QtyOnHand) FROM M_StorageOnHand
WHERE AD_Client_ID = 1000000) as target_qty;
カットオーバー計画
カットオーバーは、組織がレガシーシステムから iDempiere に切り替える重要な瞬間です。綿密な計画とリハーサルが不可欠です。
カットオーバー手順
- データ凍結:定められた時間(通常は金曜日の業務終了時または会計期間の終了時)にレガシーシステムでのすべてのデータ入力を停止します。
- 最終データ抽出:前回のリハーサル抽出以降に入力されたトランザクションを含む、レガシーシステムからの最新データを抽出します。
- 移行実行:本番の iDempiere データベースに対して移行スクリプトを実行します。リハーサルの経験に基づいて、これは高度に自動化されているべきです。
- 検証:自動検証スクリプトを実行し、指名されたビジネスユーザーが重要なデータのスポットチェックを行います。
- Go/No-Go の決定:検証結果に基づいて、本番稼働に進むかロールバックするかを決定します。
- 本番稼働:ユーザーの iDempiere へのアクセスを有効にします。レガシーシステムは参照用に読み取り専用モードで利用可能な状態を維持します。
並行運用
高リスクの移行の場合、レガシーシステムと iDempiere の両方にトランザクションを入力する並行運用期間(通常 1〜3 か月)がセーフティネットを提供します。各期間の終了時(日次、週次、または月次)に結果を比較して差異を特定します。並行運用はコストが高い(二重データ入力)ですが、最大の信頼性を提供します。
ロールバック計画
常にロールバック計画を用意してください。カットオーバー前に、iDempiere データベースの完全バックアップを取得します。移行が検証に失敗した場合や、本番稼働後に重大な問題が発見された場合は、バックアップをリストアし、問題が解決するまでレガシーシステムでの運用を継続できます。明確なロールバック基準と決定期限を定義します(例:「日曜日の午後 6 時までに検証が完了しない場合、ロールバックする」)。
移行後のデータ品質モニタリング
データ品質はカットオーバーで終わりではありません。iDempiere での運用の最初の数週間から数か月で、移行テスト中に発見されなかったデータの問題が明らかになります。
- 日次照合:最初の 1 か月間、iDempiere のレポートの主要な財務数値を独立したソース(銀行取引明細、税務申告、レガシーシステムの読み取り専用アクセス)と照合します。
- データ品質ダッシュボード:日次で実行される SQL ベースのチェックを構築し、異常をフラグします — 孤立レコード、必須フィールドの予期しない NULL 値、重複するビジネスパートナーエントリ、会計の不均衡。
- ユーザーフィードバックチャネル:ユーザーがデータの問題を報告するための明確なプロセスを確立します。初期安定化期間中は、データ品質の問題をソフトウェアバグと同じ緊急度で扱います。
- レガシーシステムの廃止:移行後少なくとも 6〜12 か月間、レガシーシステムを読み取り専用モードで利用可能な状態に保ち、移行されなかった過去データの検索をサポートします。
まとめ
データ移行は、技術スキルとプロジェクト管理の厳密さを等しく必要とする分野です。主な成功要因は以下の通りです:
- 早期に開始する — データアセスメントとクレンジングは、計画された本番稼働の数か月前から開始できます。
- 標準エンティティには iDempiere の Import Loader を使用し、複雑なシナリオには SQL と ETL で補完します。
- 実際のカットオーバー前に完全な移行を少なくとも 3 回リハーサルします。
- 自動検証スクリプトを構築し、ソースとターゲットのデータを体系的に比較します。
- ロールバックに備える — 希望は戦略ではありません。
- 移行後の数週間、データ品質を積極的にモニタリングします。
次のレッスンでは、より広い視点に目を向けます — 要件収集から本番稼働とその後まで、iDempiere で完全なビジネスソリューションを構築する方法です。