Data migrations in Odoo are where ERP projects succeed or fail in production. Most failures are not caused by bad code. They are caused by insufficient preparation and untested assumptions about what the database actually contains.
What Makes Odoo Migrations Risky
Odoo’s ORM manages schema and data implicitly. When you upgrade a module, Odoo runs its own column additions, type changes, and many-to-many table rewrites automatically. Your custom code sits on top of that machinery, and the interaction between your logic and Odoo’s upgrade path is rarely documented.
Common sources of failure include:
- Custom fields whose values must be preserved or transformed during a type change.
- Computed fields that are recalculated with different logic after an upgrade.
- Data that was valid under the old business rules but violates constraints in the new version.
- External integrations that rely on record IDs or reference fields that shift during migration.
Migration Scripts vs. Hook Functions
Odoo provides two entry points for custom migration logic: scripts in the migrations/ folder of a module, and hook functions registered in the manifest under pre_init_hook, post_init_hook, pre_migrate, and post_migrate. These are not interchangeable.
Migration scripts are the right tool for transformations that must run at a specific version boundary. They execute when Odoo detects that a module is being upgraded and receive the installed version, tying the transformation to a precise schema state.
Hook functions run during installation or upgrade without the same version-specific targeting. Using a post-install hook for a transformation that should only run once is a common mistake that causes it to repeat on every reinstall. For production upgrades, scripts in migrations/ are more precise and easier to audit.
Testing on Production Data
No migration should reach a production window without being tested on a copy of the production database. Demo data cannot surface failures caused by real data volume, edge cases accumulated over years of use, or configurations that differ between customers.
A realistic pre-migration checklist includes:
- Restoring a recent production dump to a staging environment with the same Odoo version.
- Running the full upgrade in the exact order it will run in production.
- Verifying that critical records, reports, and integrations work correctly after the upgrade.
- Measuring how long the migration takes under real data volume.
If the migration takes significantly longer on production data than on demo, that is essential information to have before the maintenance window opens.
Handling Large Tables
A single UPDATE that rewrites millions of rows will hold locks, generate replication lag, and block operations on the same table. The safer approach is batch processing: transforming records in controlled chunks with a commit between each batch. This keeps lock duration short and allows the process to be interrupted and resumed.
Additional considerations:
- Rebuild indexes after the transformation rather than maintaining them during the write.
- Log progress so the team can tell whether the process is advancing or stuck.
- Prefer adding a new column and backfilling it over modifying an existing column when the transformation is complex.
Preserving Business Rule Integrity
Schema correctness is the easy part. After an upgrade, data must be semantically consistent with how the company operates. This means checking things that automated tests rarely cover: whether open sales orders carried forward correctly, whether stock valuations match the general ledger, and whether user permissions still map to the right roles.
Define a short list of business invariants before the migration. These are specific queries that should return the same results before and after the upgrade. Running them on staging before sign-off turns implicit assumptions into explicit confirmations.
Communicating Before the Migration Window
Before a migration window, stakeholders and the technical team should agree on:
- The start time, expected duration, and absolute cutoff for the window.
- What happens if the migration cannot be completed, including the rollback plan.
- Which business functions will be unavailable and for how long.
- Who owns the go or no-go decision if issues appear during execution.
Migrations that happen without this alignment put the technical team in an impossible position. They must make consequential decisions under pressure, without the authority to make them. Treating a data migration as a coordinated business event, not a purely technical task, is what separates teams that upgrade successfully from those that do not.