Migration of data plays a vital role when upgrading or migrating between systems in Odoo. It is imperative that you ensure data correctness and integrity irrespective of whether you are migrating from an earlier Odoo version or importing data from other sources.
Migration alone does not suffice since you also need to validate the data to ensure proper functioning after migration. This article discusses the importance of validation, some of the challenges faced, and tips on how to validate migration data in Odoo.
Why validation matters in Odoo migrations
A transition to Odoo from a traditional ERP or spreadsheet application or even from another Odoo version is always more than simply technical. It's a trust issue because your end users and financial departments need their data to be right, right from the start.
Data validation is the process of validating the completeness, accuracy, consistency, and usability of the data after migration. Failing to validate your data can lead to corrupted data, broken workflows, problems in reconciling finances, and, most importantly, a lack of trust in the platform.
The four phases of data validation
- Phase 01 – Structural Validation:
This phase ensures that all required fields are filled, data types are accurate, and no technical import errors occurred during migration.
- Phase 02 – Record Count Validation:
In this stage, the total number of records in Odoo is compared with the source system to ensure completeness of migration.
- Phase 03 – Business Logic Validation:
This phase verifies that financial data, inventory values, and relationships between records are consistent and aligned with the source system.
- Phase 04 – User Acceptance Validation:
Key users perform validation by reviewing sample records and workflows to confirm that the system operates correctly in real business scenarios.
Pre-migration: prepare your data baseline
Prior to anything else, get a good sense of what you will be migrating. This serves as your guide for validating everything moving forward.
Source Data Inventory
- Tally the number of records in each entity: customers, suppliers, products, invoices, inventory transactions, and accounting entries
- Key figures to note include: total receivables, total payables, total inventory value, outstanding SO/PO orders
- Record any discrepancies in the source database – duplicate records, nulls, improper formatting
- Create a CSV or Excel export of each primary model for verification
Common data issues and how to catch them
1. Missing required fields
Odoo's models have mandatory fields partner_id on invoices, product_id on order lines, and account_id on journal items. These are enforced by Python constraints, so missing values will cause import errors or silently incomplete records.
Run a query after import to count records where these fields are null. In PostgreSQL directly:
SELECT COUNT(*) FROM account_move
WHERE move_type IN ('out_invoice','in_invoice')
AND partner_id IS NULL;
2. Duplicate records
Customers and products are common duplication sources, especially when migrating from systems that didn't enforce uniqueness. Odoo's deduplication tools help, but validate first.
SELECT name, COUNT(*) as cnt
FROM res_partner
WHERE active = true
GROUP BY name
HAVING COUNT(*) > 1
ORDER BY cnt DESC;
3. Broken relational links
Many-to-one links like product_id on stock moves or categ_id on products can break during migration if IDs don't map correctly. Always validate foreign key integrity after each import batch.
4. Incorrect financial balances
This is the most critical category. Compare your Odoo trial balance against your source system's exported trial balance at the migration date. Any discrepancy must be investigated before go-live.
Validation using Odoo tools and Python scripts
Using Odoo's built-in import log
An import done through Settings > Technical > Import and list view’s CSV import is always recorded by Odoo in the import log with statuses for each row. One should never ignore warnings but should check the import log for them.
Odoo shell queries
Access the Odoo shell to run model-level queries directly. This is faster than the UI for bulk validation:
$ odoo-bin shell -d your_database
# Count migrated partners
env['res.partner'].search_count([('customer_rank', '>', 0)])
# Check products without categories
env['product.template'].search([('categ_id', '=', False)])
Python validation script pattern
Write a reusable validation script that compares source counts from your baseline CSV against Odoo record counts via the XML-RPC API:
import xmlrpc.client, csv
url = 'http://your-odoo-instance.com'
db, user, pwd = 'mydb', 'admin', 'password'
common = xmlrpc.client.ServerProxy(f'{url}/xmlrpc/2/common')
uid = common.authenticate(db, user, pwd, {})
models = xmlrpc.client.ServerProxy(f'{url}/xmlrpc/2/object')
odoo_count = models.execute_kw(
db, uid, pwd,
'res.partner', 'search_count',
[[['customer_rank', '>', 0]]]
)
with open('baseline_customers.csv') as f:
source_count = sum(1 for _ in csv.reader(f)) - 1 # minus header
print(f"Source: {source_count} | Odoo: {odoo_count}")
if source_count != odoo_count:
print("MISMATCH -- investigate before go-live")
Post-migration reconciliation checklist
Use this checklist as your final gate before declaring the migration complete:
- The record counts are aligned with the baseline counts for: customers, vendors, products, sales orders, purchase orders, invoices, and inventory transactions.
- The trial balance is consistent between Odoo and the exported trial balance from the old system at the point of migration.
- Accounts Receivable Aging Report matches the source records.
- Accounts Payable Aging Report matches the source records.
- Inventory valuation per product category matches the valuation report from the source.
- All outstanding Sales Orders and Purchase Orders match the source records.
- Bank accounts for customers and vendors are correctly mapped.
- Taxes have been allocated correctly for each product and partner.
- Access rights have been set up and verified by the department.
- All automated actions, jobs, and emails are working properly.
However, the validation process during an Odoo migration isn't something that is done once, but rather a recurring activity throughout the whole process, starting from setting up the baseline before the migration, all the way to reconciling after the system is live. This effort in doing validations will surely pay off many times over in avoiding rework, regaining user confidence, and getting the Odoo implementation off to the right start.
Take each stage step-by-step, use automation wherever possible through shell scripting and XML-RPC API, but always do the necessary user acceptance testing. Ultimately, the Odoo migration is only a success when the end users declare the data correct.
To read more about How to Export Legacy System Data for Migration in Odoo 19, refer to our blog How to Export Legacy System Data for Migration in Odoo 19.