When upgrading an Odoo instance to a newer version, updating the code alone is not enough. Changes in models, fields, and business logic often require existing data to be adjusted to match the new structure. This is where upgrade (migration) scripts become essential.
In Odoo 19, upgrade scripts provide a structured way to transform and align data during module upgrades. They help ensure that your system continues to function correctly after changes are applied.
This blog explains how upgrade scripts work, how to structure them, and how to implement them effectively in real-world scenarios.
What are Upgrade Scripts in Odoo?
Upgrade scripts are Python files that run automatically when a module is upgraded. Their purpose is to modify existing database records so they remain compatible with updated code.
They are commonly used to:
- Adjust data after schema changes
- Rename fields or models
- Recompute stored values
- Remove outdated or inconsistent data
Instead of manually fixing data after an upgrade, these scripts automate the process in a controlled and repeatable way.
Why Upgrade Scripts are Important
During version upgrades, several structural changes can occur:
- Fields may be renamed or removed
- Models may be merged or redesigned
- Business logic may change
Without proper data migration:
- Errors may occur in the UI
- Data may become inconsistent
- Features may stop working
Upgrade scripts ensure:
- Smooth transitions between versions
- Data integrity is preserved
- Compatibility with updated modules
They are especially important for custom modules, where automatic migration is not handled by Odoo.
Directory Structure of Upgrade Scripts
Upgrade scripts must follow a specific structure inside the module directory.
your_module/
+-- migrations/
+-- 19.0.1.0/
+-- pre-migration.py
+-- post-migration.py
Explanation:
- migrations/ > Contains all upgrade scripts
- Version folder > Matches the module version
- pre-migration.py > Runs before module update
- post-migration.py > Runs after module update
The version folder name determines when the script is executed.
Types of Migration Scripts
1. Pre-Migration Scripts
These scripts run before the module is upgraded.
They are used to:
- Prepare or clean data
- Rename fields or tables
- Ensure compatibility with new schema
Example:
def migrate(cr, version):
cr.execute("""
UPDATE res_partner
SET name = 'Default Name'
WHERE name IS NULL
""")
2. Post-Migration Scripts
These scripts run after the module upgrade is completed.
They are used to:
- Transform data
- Populate new fields
- Recompute values
Example:
def migrate(cr, version):
cr.execute("""
UPDATE sale_order
SET note = 'Updated during migration'
WHERE note IS NULL
""")
Common Use Cases
1. Renaming Fields
When a field name changes in code, the database must reflect that change.
Example scenario:
- customer_name > partner_name
Without migration, the data would be lost or inaccessible.
2. Moving Data Between Models
If data needs to be transferred due to structural changes:
def migrate(cr, version):
cr.execute("""
UPDATE new_model nm
SET value = old_model.value
FROM old_model
WHERE old_model.id = nm.old_id
""")
3. Recomputing Stored Fields
If the logic of a computed field changes, existing values may no longer be valid. Migration scripts can trigger updates to ensure consistency.
4. Cleaning Obsolete Data
Upgrade scripts can remove:
- Deprecated records
- Invalid configurations
- Unused references
This keeps the database clean and efficient.
Writing an Upgrade Script
Every upgrade script must define a migrate function:
def migrate(cr, version):
# cr: database cursor
# version: previous module version
cr.execute("UPDATE res_partner SET active = TRUE WHERE active IS NULL")
Key Points:
- Uses the database cursor (cr)
- Executes SQL or controlled operations
- Runs automatically during module upgrade
When are Upgrade Scripts Executed?
Upgrade scripts are triggered when:
- A module is upgraded using -u module_name
- A database is migrated to a newer version
They are executed in sequence based on the version folders defined in the module.
Best Practices for Writing Upgrade Scripts
1. Always Backup Your Database
Before running any migration, ensure a full backup is available.
2. Test in a Staging Environment
Never run migration scripts directly on production without testing.
3. Keep Scripts Safe to Re-run
Ensure scripts do not fail or duplicate data if executed more than once.
4. Prefer SQL for Large Data Updates
For performance reasons, SQL is often more efficient than ORM for bulk operations.
5. Minimize Use of sudo-like Logic
Avoid bypassing access rules unless absolutely necessary.
6. Handle Dependencies Carefully
Ensure related models and fields exist before modifying data.
Common Mistakes to Avoid
- Skipping migration scripts for custom modules
- Writing scripts without testing
- Performing irreversible operations without backup
- Ignoring data dependencies
- Using inefficient queries on large datasets
Upgrade scripts in Odoo 19 play a vital role in ensuring that data remains consistent and usable after system updates. They allow developers to safely handle changes in structure, logic, and relationships between models.
By organizing scripts correctly, choosing the right migration phase, and following best practices, developers can avoid common pitfalls and ensure smooth upgrades.
A well-prepared migration process is the key to maintaining stability and reliability in any Odoo implementation.
By implementing upgrade scripts properly, you can confidently manage Odoo upgrades while preserving data integrity and system stability.
To read more about How to Migrate Custom Modules from Odoo 18 to Odoo 19, refer to our blog How to Migrate Custom Modules from Odoo 18 to Odoo 19.