Skip to content

Odoo Migration with OpenUpgrade: Step-by-Step Guide

DeployMonkey Team · March 22, 2026 15 min read

What Is OpenUpgrade?

OpenUpgrade is an OCA (Odoo Community Association) project that provides migration scripts for upgrading between Odoo versions. It handles: database schema changes, data transformations, renamed fields/models, and removed features. It is the standard tool for Community Edition migrations.

When to Use OpenUpgrade

  • Migrating Odoo Community Edition (free)
  • Single version jumps (e.g., 17 → 18, 18 → 19)
  • When you cannot use Odoo.sh (Enterprise only)
  • When you want full control over the migration process

Prerequisites

  • Working Odoo installation of the target version
  • Full database backup of the source version
  • Source code of both versions
  • Git and Python environment
  • Test server (never migrate directly on production)

Step 1: Backup Source Database

# Full backup — CRITICAL: do this first!
pg_dump -U odoo -Fc source_db > /backups/pre_migration_$(date +%Y%m%d).dump

# Also backup filestore
tar -czf /backups/filestore_$(date +%Y%m%d).tar.gz \
    /var/lib/odoo/.local/share/Odoo/filestore/source_db/

# Verify backup
pg_restore -l /backups/pre_migration_$(date +%Y%m%d).dump | head -5

Step 2: Clone OpenUpgrade

# Clone OpenUpgrade for the TARGET version
git clone https://github.com/OCA/OpenUpgrade.git --branch 19.0 /opt/openupgrade

# Install dependencies
cd /opt/openupgrade
pip install -r requirements.txt
pip install openupgradelib  # Helper library

Step 3: Restore Source Database on Test Server

# Create test database
createdb -U odoo migration_test

# Restore source backup
pg_restore -U odoo -d migration_test /backups/pre_migration.dump

# Copy filestore
cp -r /var/lib/odoo/.local/share/Odoo/filestore/source_db/ \
     /var/lib/odoo/.local/share/Odoo/filestore/migration_test/

Step 4: Run OpenUpgrade

# Run the migration
python /opt/openupgrade/odoo-bin \
    -d migration_test \
    --update all \
    --stop-after-init \
    --load=base,web,openupgrade_framework \
    --addons-path=/opt/openupgrade/addons,/opt/odoo/custom-addons \
    --logfile=/var/log/odoo/migration.log

# This can take 10 minutes to several hours depending on database size

Step 5: Check Migration Log

# Look for errors
grep -i "error\|warning\|failed" /var/log/odoo/migration.log | head -50

# Look for OpenUpgrade-specific messages
grep "openupgrade" /var/log/odoo/migration.log | tail -20

# Common warnings (usually safe to ignore):
# "Field X is not found" — renamed in new version
# "Table X does not exist" — removed in new version

# Real errors to fix:
# "FATAL" — migration script failed
# "IntegrityError" — data constraint violated
# "AttributeError" — missing method in custom module

Step 6: Verify Data Integrity

# Compare record counts
SELECT 'res_partner' as model, count(*) FROM res_partner
UNION ALL
SELECT 'sale_order', count(*) FROM sale_order
UNION ALL
SELECT 'account_move', count(*) FROM account_move
UNION ALL
SELECT 'product_product', count(*) FROM product_product
UNION ALL
SELECT 'stock_move', count(*) FROM stock_move;

# Compare against source database counts
# Any significant difference needs investigation

# Check financial totals
SELECT SUM(amount_total) FROM account_move WHERE move_type = 'out_invoice';
# Should match source database

Step 7: Migrate Custom Modules

# Custom modules need manual adaptation:

# 1. Update __manifest__.py version
'version': '19.0.1.0.0',

# 2. Fix breaking changes (varies by version)
# Common changes 18 → 19:
# - _sql_constraints → models.Constraint
# -  → 
# - attrs dict → direct attributes

# 3. Install adapted module
python odoo-bin -d migration_test -i custom_module --stop-after-init

# 4. Run custom module tests
python odoo-bin -d migration_test --test-tags /custom_module --stop-after-init

Step 8: Functional Testing

Test every critical business process:

  1. Login as different user roles
  2. Create and confirm a sale order
  3. Create and post an invoice
  4. Process a payment
  5. Run bank reconciliation
  6. Check inventory operations
  7. Generate PDF reports
  8. Send an email from Odoo
  9. Check all dashboards and KPIs
  10. Verify all cron jobs run correctly

Step 9: Production Migration

# Only after thorough testing:

# 1. Announce maintenance window
# 2. Stop production Odoo
systemctl stop odoo

# 3. Final backup
pg_dump -U odoo -Fc production > /backups/final_pre_migration.dump

# 4. Run migration on production database
python /opt/openupgrade/odoo-bin \
    -d production \
    --update all \
    --stop-after-init \
    --load=base,web,openupgrade_framework

# 5. Start new version Odoo
systemctl start odoo

# 6. Verify health check
curl -f http://localhost:8069/web/health

# 7. Monitor closely for 24-48 hours

Rollback Plan

# If migration fails:
systemctl stop odoo

# Restore pre-migration backup
dropdb -U odoo production
createdb -U odoo production
pg_restore -U odoo -d production /backups/final_pre_migration.dump

# Restore filestore
rm -rf /var/lib/odoo/.local/share/Odoo/filestore/production/
tar -xzf /backups/filestore_pre_migration.tar.gz -C /

# Start OLD version Odoo
systemctl start odoo

Multi-Version Jumps

# OpenUpgrade supports ONE version at a time:
# 15 → 16 → 17 → 18 → 19
# Each step requires running OpenUpgrade for that target version

# For large jumps (14 → 19), consider:
# Option A: Sequential migration (5 steps, most reliable)
# Option B: Fresh install + data migration (import key data only)
# Option C: Hybrid (migrate to intermediate version, then fresh + import)

DeployMonkey

DeployMonkey simplifies Odoo migrations. Deploy a test instance of the new version, use the AI agent to identify custom module changes needed, run the migration on staging, and verify before touching production.