Odoo Data Migration Playbook
Data migration is where most Odoo projects quietly bleed budget. Not because the technical task is hard — it isn't — but because nobody owns the data quality decisions, and they get made by an intern with a spreadsheet at 11pm the night before go-live.
We've migrated data into Odoo for retailers, manufacturers, service firms and distributors. The playbook is roughly the same every time: get the targets right, clean upstream, migrate in waves, validate hard. The teams that follow it go live with confidence; the teams that improvise spend the first month after go-live fixing data instead of running their business.
This guide is the version we hand to clients on day one of the migration workstream. Read it before you export anything from your legacy system. Especially if your legacy system is a folder of Excel files — those projects are the ones that go sideways fastest, in our experience.
Decide what migrates and what doesn't — before you touch a tool
The single best decision on a migration is what NOT to migrate. Old customers who haven't ordered in three years? Archive, don't migrate. Products discontinued five years ago but still in the catalogue? Same. Open invoices from 2019 that legal has written off? Don't migrate, document.
Less data in Odoo means faster reports, cleaner dashboards, happier users and a much lower migration cost. We've seen ERP databases shrink 60% during migration with no loss of value to the business — and a measurable performance gain afterwards.
- Decide what migrates and what doesn't — first and most important call
- Archive old customers, products, transactions — don't move them
- Open transactions only — closed history can stay in legacy or a data warehouse
- Less data = faster Odoo, cleaner dashboards, happier users
- Document the cut — auditors and finance will ask in year one
Master data first, transactions last
Always migrate in this order: chart of accounts, partners (customers, suppliers, contacts), products, then opening balances and open transactions. Each layer depends on the previous. Skip a step and you end up with invoices pointing at customers that don't exist, or stock moves with phantom products.
We test each layer independently before stacking the next. Partners load and validate? Then products. Products load and validate? Then opening AR/AP. The discipline pays back every time because errors are isolated to the layer where they occurred.
- Order: chart of accounts → partners → products → opening balances → open transactions
- Test each layer independently before stacking the next
- Partners include customers, suppliers, contacts — separate the imports
- Products include variants, units of measure, BoMs — model carefully
- Opening balances reconcile to legacy trial balance to the cent
Cleaning happens upstream, not in Odoo
Don't import dirty data and clean it in Odoo. Clean it in the staging spreadsheet or staging database, then import the clean version. Cleaning in Odoo means cleaning live data, which means risk to operations, audit issues and much slower work.
Build a staging area that mirrors the Odoo target schema. Do all the deduplication, address normalisation, field mapping and validation there. The import to Odoo should be boring: well-structured CSVs going into well-defined models, with an audit trail of what was loaded when.
- Clean upstream in staging, never live in Odoo
- Staging schema mirrors Odoo target — same fields, same types
- Deduplicate partners, normalise addresses, validate VAT before import
- Field mapping documented in a spreadsheet everyone agrees on
- Audit trail of what was loaded when, by whom, with which file
Migrate in waves — never big-bang
We always run at least three migration waves: a first to discover the real shape of the data, a second to validate the cleaned set, and a final cut-over migration into production. Many projects need four or five. Each wave produces a known-good import script and known-good data.
The cut-over wave is rehearsed on a staging copy of production, ideally twice. We time it, document each step, have a roll-back plan. The aim is that on the actual go-live night, nothing is being done for the first time.
- Three to five migration waves — never one big-bang attempt
- Wave 1 = discovery, Wave 2-3 = clean, final wave = cut-over
- Cut-over rehearsed at least twice on staging, timed and documented
- Roll-back plan defined and tested — what happens if cut-over fails halfway
- Each wave produces a known-good import script for the next
Validation that actually catches problems
Counts and totals — partner count, product count, AR total, AP total, stock value — must reconcile to the legacy system to the cent or unit. If they don't, something is wrong, and you find out now, not in month-three reporting.
Beyond totals, we always sample 50 records of each type and walk them end-to-end with a domain expert. Customer Acme — does the address look right, the payment terms, the tax rules, the price list? Sampling catches the data problems that totals don't.
- Reconcile counts and totals to the cent / unit against legacy
- Sample 50 records per type, walk end-to-end with a domain expert
- Run trial balance and inventory valuation in both systems day 1 of go-live
- Validate VAT numbers against official registers (VIES) for EU partners
- Sign-off from finance, sales, supply chain before declaring migration done
Migration mistakes that cost the most money
These are the mistakes we see ruin migrations for clients who didn't engage us upfront.
- Migrating everything because nobody dared to make the cut decision — bloated database from day one.
- Cleaning data in Odoo after import — risk to live ops, audit issues, much slower work.
- Single big-bang migration — no rehearsal, no rollback, panic on go-live night.
- No reconciliation against legacy totals — month-three reporting reveals the problems.
- Domain experts not involved in sample validation — technical migration passes, business uses garbage.
Metrics that prove the migration succeeded
These are the numbers we ask for at go-live + 30 days. They show whether the data is trustworthy.
- Trial balance in Odoo matches legacy trial balance to the cent at cut-over.
- Stock valuation in Odoo matches legacy stock valuation to the unit at cut-over.
- Zero data-related blocking issues in week one of operations.
- Sample of 50 partners, 50 products, 50 transactions validated end-to-end by domain experts.
- Database size 30-60% smaller than legacy — proof the cut decisions worked.
How we run data migrations at Flydoo
We start every migration with a 'data day' workshop — sales, supply chain, finance, IT in a room for half a day deciding what migrates and what doesn't. The output is a written scope document signed by the heads of each function. That scope is the contract for the migration workstream.
From there it's discipline: staging area, mapping document, wave plan, rehearsal, cut-over, validation. Nothing fancy. What separates a smooth migration from a painful one isn't tooling — it's the willingness to do the boring work in the right order.
- Data day workshop — written scope signed by heads of each function
- Staging area mirrors Odoo target schema, all cleaning done there
- Three to five migration waves — discovery, clean, cut-over
- Cut-over rehearsed twice on staging copy, timed and documented
- Validation by domain experts before declaring done — no exceptions
Practical checklist for a data migration that won't sink your go-live
Walk this list with your project lead and finance. Most ticked = healthy migration.
- Cut decision documented — what migrates, what doesn't, signed by function heads
- Staging area built mirroring Odoo schema
- Field mapping documented in a shared spreadsheet, signed off
- Three or more migration waves planned and scheduled
- Cut-over rehearsed at least twice on staging copy of production
- Rollback plan defined and tested
- Reconciliation queries (trial balance, stock value, AR/AP) ready and run on both systems
- Domain experts available for sample validation in week one
Key takeaways
- The most important migration decision is what NOT to migrate — make it early, in writing
- Order matters: chart of accounts → partners → products → opening balances → open transactions
- Clean upstream in staging, never live in Odoo after import
- Migrate in waves — discovery, clean, cut-over — never big-bang
- Reconcile totals to the cent and sample-validate with domain experts
- Database 30-60% smaller than legacy is a healthy sign, not a failure
Frequently asked questions
How long does an Odoo data migration take?
For an SME with one ERP, decent legacy data and a clear cut decision, we usually plan 4-8 weeks of migration work in parallel with configuration. For a multi-entity group with several legacy systems and dirty data, 3-6 months. The variable that drives time isn't volume — it's data quality and the number of decisions to make about what to keep.
Should we migrate historical transactions or just open ones?
Open ones, almost always. Closed history (paid invoices, completed sales orders, old stock moves) can stay in the legacy system or in a data warehouse for reference. Migrating closed history into Odoo bloats the database, slows reports, and adds risk for very little value. Auditors care about the trial balance at cut-over, not the line items from 2018.
Can we migrate from another ERP automatically?
Tools exist — Odoo's import, OCA modules, custom ETL — but 'automatic' is the wrong word. The work is in mapping, cleaning and deciding, not in moving bytes. We use Python scripts for repeatable transformations and Odoo's import wizard for the final load, but the upstream work is always manual judgement.
What if the legacy data is genuinely a mess (e.g. shared Excel files)?
Then the migration project becomes a data-quality project first. We've helped clients reconstruct partner masters from invoice PDFs, deduplicate 40,000 contacts down to 12,000 real customers, and rebuild product catalogues from supplier price lists. It's slow but it's the foundation — there's no migrating around bad data.
Who should own the migration on the client side?
A dedicated client lead — usually the future Odoo product owner — backed by domain experts from finance, sales and supply chain. The technical migration team (us, or your IT) takes instructions from them. Migrations led by IT alone, with no business owner, are the ones that produce technically clean data nobody trusts.
Need help applying any of this to your own context? We're happy to talk.
