Migration script development


As explained with more detail in the page “Migration Manager” (The Odoo Migration Manager), the migration scripts of a module are usually the combination of 3 python files (might be less if some steps are not necessary):

  • pre-migration.py

  • post-migration.py

  • end-migration.py

Since version 14, these files can be found here:


Each of those files will contain a function migrate which is called by the Migration Manager.

Then, the function migrate will call other functions. Each of these functions will execute a task of the migration, these functions are the one which needs most of the work from developers. These functions are usually declared in the same file.

Luckily, many pre-existing functions already exist within openupgradelib reducing significantly the work of development. See OpenUpgrade API

For many modules, a developer will not even need to write any function, but will “simply” need to call pre-existing functions from openupgradelib with the appropriate arguments. The main complexities becomes to learn what are the functions available in openupgradelib and then to select appropriatly the arguments (usually according to the openupgrade_analysis.txt, see below).

For instance, the migration to version 13 of mass_mailing did not require any custom function: https://github.com/OCA/OpenUpgrade/pull/2273/files

After this introduction, which highlight how simple the migration scripts can be, do not underestimate the power of OpenUpgrade. The migration of the account module to version 13 is the kind of situation where the full power of OpenUpgrade was unleashed to successfully overcome the “acc-pocalypse”: https://github.com/OCA/OpenUpgrade/pull/2275/files.

Learn from typical Use cases

Learn from existing migration scrips

Since version 14, the migration scripts are located in:


During the review for a given module, you can follow this process:

  • Review the analysis (read more in Migration Files). First the file openupgrade_analysis.txt showing some differences between the 2 versions of the module. Then, openupgrade_analysis_work.txt to see what the developer planned to do.

  • Then you can check the other files to see how the plan was achieved.

You should pick modules with which you are familiar with in both version and for which you are aware of the changes.

Learn from code review of open PRs


This will engage you in a discussion with other contributors and help you understand how developers selected one way or another to implement the migration scripts.

The Trial and error process for the development of your scripts

Basically, this is the happening during the step when you try to run the upgrade described in Running the migration:

  • [A] get the copy of your database in old version as db-upgrade, it is easy to do through the database manager of your old odoo http://localhost:8069/web/database/manager

  • [B] run odoo -d db-upgrade -u all --stop-after-init

  • [C] In case of error, fix the error adding or editing migration scripts within the module to fix, then rerun with -u <fixed_module> instead of -u all. This way of running is only done for testing purposes and will help you save a lot of time in the development process. Whenever facing unexpected errors, you might want to restart from [A] as this step will leave your database in an inconsistent state.

  • [D] After all issues are fixed go back to --update all to ensure that all dependent modules have been upgraded.

Restart the upgrade of the failed module instead of upgrading all systematically

As an alternative to the step [C] mentioned above…

In case of error, fix the error (adding or editing migration scripts), then rerun without the --update all: odoo -d db-upgrade --stop-after-init. This will continue the upgrade process from where it left off, starting with the module that caused the error. That way, the migration will not run the end-migration scripts of the modules that were already upgraded before the error. But in case of a live migration you always need to restore the database.

Note that for the time being, this is not available in all versions (see explanations here: https://github.com/OCA/OpenUpgrade/pull/2499). It is available only for 12 and 13: https://github.com/OCA/OpenUpgrade/pulls?q=is%3Apr+%5BFIX%5D+reset+exception

Learning resources

You can also refer to the following: