ERP Data Migration for Accurate and Risk-Free Odoo Adoption

The sales record contains 14,000 rows dating back to 2012. The inventory spreadsheet tracks stock using units of measurement that are now obsolete. Customer data is scattered across three systems: the legacy CRM, accounting software from 2018, and a Google Sheets file created by the sales team last quarter.

Any ERP implementation begins with data. Before configuring a single module or developing customizations, the information must be transferred. An incorrect transfer carries the risk of discovering—even six months later—that outstanding invoices are linked to the wrong partner or that product codes (SKUs) do not match those used for warehouse order picking.

Data migration is the most critical phase of an Odoo implementation. This is not due to tool limitations—Odoo’s import/export system is robust—but rather because no one truly verifies their data quality until they attempt to transfer it elsewhere.

Why Migration Fails in Practice

Three patterns tend to derail most ERP migrations. Teams treat migration as a one-off technical task rather than a project phase with its own timeline and validation stages. They load all the data over a weekend, discover on Monday morning that customer credit limits are missing, and spend the following week manually correcting records.

The state of the data is worse than anyone admits. Legacy systems allow users to enter free-form text without restrictions. A phone number field might contain the note “call after 2 p.m.” A customer state or province column might mix “CA,” “California,” and “Cal.” This often goes unnoticed until the import process rejects 12% of the records.

Relational integrity breaks down during imports. Business partners and products load correctly; however, the link between a partner’s default delivery address and the inventory location supplying it requires a specific sequence, knowledge of foreign keys, and sometimes manual reconciliation that no one had anticipated.

An Odoo implementation partner experienced in this process is aware of these potential pitfalls and designs the migration plan with them in mind. The discipline of data migration exists precisely because the ideal scenario never survives contact with real production data.

Phase One: Source Data Assessment

Before writing a single import script, evaluate the available resources. Perform a full export from all legacy systems: the production database, archived backups, and spreadsheets used by users as workarounds. Next, analyze the characteristics of each export:

  • Which fields are consistently populated, and which are empty in 80% of cases?
  • Are there duplicate records that need to be merged before import?
  • Do date fields use the same format across different sources?
  • Which lookup tables did users bypass in favor of free-text notes?

Identify and flag any critical issues before beginning the mapping phase. The old system might store prices in a different currency, or the chart of accounts might use a completely different numbering scheme.

Extract a data dictionary from each source and compare their structures. If you find the same customer listed with slightly different names across the three databases, decide in advance whether to merge the records, remove duplicates, or flag them for manual review

Phase Two: Mapping and Transformation

Odoo’s data model has a specific, predefined structure. The `res.partner` model consolidates information that other systems typically split across separate tables for customers, contacts, and addresses. Conversely, the `product.product` model requires fields such as `default_code` and `barcode`, which might not exist in your previous warehouse management system.

Before using Odoo’s import interface, create a field mapping document. For each source field, note the following:

The corresponding model and field in Odoo.

Any necessary transformations (date format conversion, currency normalization, conversion of enumerated values).

Whether the field is mandatory in Odoo and how to provide a default value if it is missing from the source.

The uniqueness constraint that determines how duplicates are handled.

For relational fields—such as *many2one* links between companies and their contacts, or between products and supplier information—map the foreign keys first. Odoo imports rely on XML IDs; therefore, you need a stable reference that remains unchanged even if data is reloaded. Generate these references from the source data before starting the import, not after.

Perform transformations on “dirty” data directly in the export file, not within Odoo. Normalize country names by converting them to ISO codes and remove non-numeric characters from phone numbers. Standardize status fields to match Odoo’s selection lists. Completing these tasks beforehand turns the import into a simple upload procedure, saving you from having to solve a complex puzzle full of edge cases.

Phase Three: Import Execution

Odoo offers several import methods. Importing CSV files via the user interface is suitable for small datasets and provides immediate feedback on any errors; the `base_import` module handles field mapping and the preview. For larger-scale migrations, the `base_import_module` approach allows you to prepare a data file that is processed via the ORM, ensuring full validation.

Plan the import in the following order:

  1. Basic data: currencies, countries, taxes, units of measure
  2. Partners and contacts
  3. Products and categories
  4. Warehouse locations and initial stock levels
  5. Sales and purchase data
  6. Accounting: chart of accounts, journal entries, outstanding invoices

Each step assumes the previous one has been successfully completed using the appropriate XML IDs. If products reference partner (vendor) IDs, those partners must already exist in the system; likewise, if invoices reference product IDs, the products must exist before the invoices are loaded. Break the source data dependency chain by identifying independent records and loading them before the records that reference them.

Always perform each import in a staging instance. Thanks to Odoo’s `–i18n-overwrite` parameter and the ability to delete and recreate the database, you can iterate within the staging environment until the data matches the totals from the source system. Compare the number of rows, the sum of outstanding invoices, and customer balances. If, after three import attempts, the data in the staging instance does not match the source data, the issue lies in the mapping or the quality of the source data, not in the import tool itself.

Phase Four: Validation and Reconciliation

A successful import means that data has been loaded without errors. A successful migration means that the data is correct.

Reconciliation involves running queries after the import—on both the legacy database and Odoo—to verify that the aggregated results match:

  • Total number of active customers
  • Product count by category
  • Sum of receivables by due date
  • Inventory value by location

If the aggregated data differs, trace the discrepancy back to the source and identify the specific records. A discrepancy could stem from a transformation error, an overlooked duplicate, or a record from the old system that should have been excluded.

Provide business users with a read-only preview in the staging environment and ask them to validate their data. The finance team will spot a misclassified invoice in five seconds—an issue that a reconciliation script might not detect for weeks. Include this review period in the project plan: two to five working days, depending on the data volume.

Cutover and Rollback

Once validation in the staging environment is complete, plan the transition to the new system (the move to production or “cutover”). Shut down the legacy system after the final data export, load the cleansed data into the Odoo production instance, and re-run the same reconciliation queries.

Keep the old database accessible in read-only mode for at least 90 days. You may need to reference pre-migration transactions; having the old system available avoids the panic of having to “re-import everything,” which could jeopardize the post-launch stabilization phase.

The goal is not to create a replica of the old system that is identical in every detail. Legacy systems accumulate unnecessary data: orphaned records, incomplete entries, and conflicting information. Migration is the ideal opportunity to clean house. Use this phase to eliminate data that adds no value to the new setup and import only the information essential for business operations. Everything else should be archived externally, not in the Odoo database.

Similar Posts