0k-odoo-upgrade
A tool for migrating Odoo databases between major versions, using OpenUpgrade in a production-like Docker environment.
Table of Contents
Prerequisites
- 0k dev-pack installed (provides the
composecommand) - Docker and Docker Compose
rsyncfor filestore copyingsudoaccess for filestore operations
Installation
git clone <repository-url>
cd 0k-odoo-upgrade
Project Structure
.
├── upgrade.sh # Main entry point
│
├── config/
│ └── compose.yml # Docker Compose configuration
│
├── lib/
│ ├── common.sh # Shared bash functions
│ └── python/ # Python utility scripts
│ ├── check_views.py # View analysis (pre-migration)
│ ├── validate_views.py # View validation (post-migration)
│ ├── fix_duplicated_views.py # Fix duplicated views
│ └── cleanup_modules.py # Obsolete module cleanup
│
├── scripts/
│ ├── prepare_db.sh # Database preparation before migration
│ ├── finalize_db.sh # Post-migration finalization
│ └── validate_migration.sh # Manual post-migration validation
│
└── versions/ # Version-specific scripts
├── 13.0/
│ ├── pre_upgrade.sh # SQL fixes before migration
│ ├── upgrade.sh # OpenUpgrade execution
│ └── post_upgrade.sh # Fixes after migration
├── 14.0/
├── ...
└── 18.0/
How It Works
Overview
The script performs a step-by-step migration between each major version. For example, to migrate from 14.0 to 17.0, it executes:
14.0 → 15.0 → 16.0 → 17.0
Process Steps
-
Initial Checks
- Argument validation
- Required command verification (
docker,compose,sudo,rsync) - Source database and filestore existence check
-
Environment Preparation
- Creation of a fresh Odoo database in the target version (for module comparison)
- Copy of the source database to a working database
- Filestore copy
-
Database Preparation (
scripts/prepare_db.sh)- Neutralization: disable mail servers and cron jobs
- Detection of installed modules missing in the target version
- View state verification
- User confirmation prompt
-
Migration Loop (for each intermediate version)
pre_upgrade.sh: version-specific SQL fixes before migrationupgrade.sh: OpenUpgrade execution via Dockerpost_upgrade.sh: fixes after migration
-
Finalization (
scripts/finalize_db.sh)- Obsolete sequence removal
- Modified website template reset
- Compiled asset cache purge
- Duplicated view fixes
- Obsolete module cleanup
- Final update with
-u all
Flow Diagram
┌─────────────────┐
│ upgrade.sh │
└────────┬────────┘
│
▼
┌─────────────────┐ ┌─────────────────┐
│ Initial │────▶│ Copy DB + │
│ checks │ │ filestore │
└─────────────────┘ └────────┬────────┘
│
▼
┌─────────────────┐
│ prepare_db.sh │
│ (neutralization)│
└────────┬────────┘
│
┌───────────────────────┼───────────────────────┐
│ │ │
▼ ▼ ▼
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ versions/13.0/ │────▶│ versions/14.0/ │────▶│ versions/N.0/ │
│ pre/upgrade/post│ │ pre/upgrade/post│ │ pre/upgrade/post│
└─────────────────┘ └─────────────────┘ └────────┬────────┘
│
▼
┌─────────────────┐
│ finalize_db.sh │
│ (cleanup) │
└─────────────────┘
Usage
Before Migration
-
Import the source database to your local machine
-
Clean up the source database (recommended)
- Uninstall unnecessary modules
- Do NOT uninstall modules handled by OpenUpgrade
-
Check module availability
- Ensure all custom modules are ported to the target version
-
Start the Docker environment
# Start the PostgreSQL container compose up -d postgres # Verify only one postgres container is running docker ps | grep postgres
Running the Migration
./upgrade.sh <source_version> <target_version> <database_name> <source_service>
Parameters:
| Parameter | Description | Example |
|---|---|---|
source_version |
Source Odoo version (without .0) | 14 |
target_version |
Target Odoo version (without .0) | 17 |
database_name |
Database name | my_prod_db |
source_service |
Source Docker Compose service | odoo14 |
Example:
./upgrade.sh 14 17 elabore_20241208 odoo14
During Migration
The script will prompt for confirmation at two points:
-
Missing modules list: installed modules that don't exist in the target version
Y: continue (modules will be marked for removal)N: abort to manually uninstall certain modules
-
View state: verification of potentially problematic views
Y: continueN: abort to manually fix issues
After Migration
-
Review logs to detect any non-blocking errors
-
Validate the migration (see Post-Migration Validation)
-
Test the migrated database locally
-
Deploy to production
# Export the migrated database vps odoo dump db_migrated.zip # On the production server vps odoo restore db_migrated.zip
Post-Migration Validation
After migration, use the validation script to check for broken views and XPath errors.
Quick Start
./scripts/validate_migration.sh ou17 odoo17
What Gets Validated
Runs in Odoo shell, no HTTP server needed:
| Check | Description |
|---|---|
| Inherited views | Verifies all inherited views can combine with their parent |
| XPath targets | Ensures XPath expressions find their targets in parent views |
| QWeb templates | Validates QWeb templates are syntactically correct |
| Field references | Checks that field references point to existing model fields |
| Odoo native | Runs Odoo's built-in _validate_custom_views() |
Running Directly
You can also run the Python script directly in Odoo shell:
compose run odoo17 shell -d ou17 --no-http --stop-after-init < lib/python/validate_views.py
Output
- Colored terminal output with
[OK],[ERROR],[WARN]indicators - JSON report written to
/tmp/validation_views_<db>_<timestamp>.json - Exit code:
0= success,1= errors found
Customization
Version Scripts
Each versions/X.0/ directory contains three scripts you can customize:
pre_upgrade.sh
Executed before OpenUpgrade. Use it to:
- Add missing columns expected by OpenUpgrade
- Fix incompatible data
- Remove problematic records
#!/bin/bash
set -euo pipefail
echo "Prepare migration to 15.0..."
copy_database ou14 ou15 ou15
PRE_MIGRATE_SQL=$(cat <<'EOF'
-- Example: remove a problematic module
DELETE FROM ir_module_module WHERE name = 'obsolete_module';
EOF
)
query_postgres_container "$PRE_MIGRATE_SQL" ou15
copy_filestore ou14 ou14 ou15 ou15
echo "Ready for migration to 15.0!"
upgrade.sh
Runs OpenUpgrade migration scripts.
post_upgrade.sh
Executed after OpenUpgrade. Use it to:
- Fix incorrectly migrated data
- Remove orphan records
- Update system parameters
#!/bin/bash
set -euo pipefail
echo "Post migration to 15.0..."
POST_MIGRATE_SQL=$(cat <<'EOF'
-- Example: fix a configuration value
UPDATE ir_config_parameter
SET value = 'new_value'
WHERE key = 'my_key';
EOF
)
query_postgres_container "$POST_MIGRATE_SQL" ou15
Available Functions
Version scripts have access to functions defined in lib/common.sh:
| Function | Description |
|---|---|
query_postgres_container "$SQL" "$DB" |
Execute an SQL query |
copy_database $from $to_service $to_db |
Copy a PostgreSQL database |
copy_filestore $from_svc $from_db $to_svc $to_db |
Copy a filestore |
log_info, log_warn, log_error |
Logging functions |
log_step "title" |
Display a section header |
Adding a New Version
To add support for a new version (e.g., 19.0):
mkdir versions/19.0
cp versions/18.0/*.sh versions/19.0/
# Edit the scripts to:
# - Change references from ou18 → ou19
# - Change the port from -p 8018:8069 → -p 8019:8069
# - Add SQL fixes specific to this migration
Troubleshooting
Common Issues
"No running PostgreSQL container found"
# Check active containers
docker ps | grep postgres
# Start the container if needed
compose up -d postgres
"Multiple PostgreSQL containers found"
Stop the extra PostgreSQL containers:
docker stop <container_name_to_stop>
"Database not found"
The source database must exist in PostgreSQL:
# List databases
docker exec -u 70 <postgres_container> psql -l
# Import a database if needed
docker exec -u 70 <postgres_container> pgm restore <file.zip>
"Filestore not found"
The filestore must be present at /srv/datastore/data/<service>/var/lib/odoo/filestore/<database>/
Restarting After an Error
The script works on a copy of the original database. You can restart as many times as needed:
# Simply restart - the copy will be recreated
./upgrade.sh 14 17 my_database odoo14
Viewing Detailed Logs
Odoo/OpenUpgrade logs are displayed in real-time. For a problematic migration:
- Note the version where the error occurs
- Check the logs to identify the problematic module/table
- Add a fix in the
pre_upgrade.shfor that version - Restart the migration
License
See the LICENSE file.