erplibre/script/odoo/migration
Mathieu Benoit 1f0b5c021f [FIX] migration 13->14: hand group_fiscal_year over to om_account_accountant
The 13.0 -> 14.0 data migration died on:

  duplicate key value violates unique constraint "res_groups_name_uniq"
  Key (category_id, name)=(9, Allow to define fiscal years of more or less
  than a year) already exists

In 13.0 that security group is declared by the core « account » module, so the
database holds it as account.group_fiscal_year. In 14.0 core account no longer
declares it and om_account_accountant (odoomates) does. Owning no XML id of its
own, the module tries to CREATE the group and collides with the existing row.

Renaming the XML id makes Odoo UPDATE the existing record instead. The record
id is untouched, so user assignments, access rights and record rules pointing
at the group survive -- on the reference database it holds none, but the fix
must not depend on that.

The fix hook also learns a « .sql » flavour, run through psql. The « .py »
flavour is piped into « odoo<target>-bin shell », which requires loading a
not-yet-migrated database with the TARGET version's registry -- precisely what
is failing at that point. A pure SQL fix needs no ORM and no registry.

Verified end to end on a throwaway copy of the stuck database: the statement
renames one row, a second run changes nothing, and the full 13->14 OpenUpgrade
then completes (« Modules loaded. », base at 14.0.1.3, zero
res_groups_name_uniq error).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-08-01 04:21:06 -04:00
..
check_cow_views.py [FIX] check_cow_views: detect on arch shape, not on mode 2026-08-01 00:54:44 -04:00
fix_migration_odoo130_to_odoo140.sql [FIX] migration 13->14: hand group_fiscal_year over to om_account_accountant 2026-08-01 04:21:06 -04:00
fix_migration_odoo140_to_odoo150.py [IMP] script: update copyright year to 2026 2026-03-11 23:16:05 -04:00
neutralize_cow_views.py [ADD] migration: neutralize the COW views that would break a version bump 2026-08-01 01:04:38 -04:00
README.base.md [IMP] migration: per-database uninstall list, with a stated reason 2026-07-31 23:25:43 -04:00
README.fr.md [IMP] migration: per-database uninstall list, with a stated reason 2026-07-31 23:25:43 -04:00
README.md [IMP] migration: per-database uninstall list, with a stated reason 2026-07-31 23:25:43 -04:00
snapshot_cow_views.py [ADD] migration: snapshot and diff the website COW views at each version bump 2026-08-01 00:58:54 -04:00
uninstall_module_list_odoo140_to_odoo150.txt [IMP] todo support odoo upgrade 2025-10-31 01:43:26 -04:00

Migration

Run this script when doing database migration. Example :

source ./.venv.odoo15.0_python3.8.20/bin/activate && cat ./script/odoo/migration/fix_migration_odoo140_to_odoo150.py | ./odoo15.0/odoo/odoo-bin shell -d DATABASE

Check uninstall_module_list_odoo140_to_odoo150.txt

Module lists to uninstall

Before a version bump, the migration uninstalls the modules listed in uninstall_module_list_odoo<from>_to_odoo<to>.txt. Two locations are read, the private one first, and the results are merged (duplicates dropped):

  1. private/odoo/migration/<database>/uninstall_module_list_odooXX0_to_odooYY0.txt — specific to ONE database, not versioned. Which modules must be dropped depends on the data, so this is where nearly every entry belongs.
  2. script/odoo/migration/uninstall_module_list_odooXX0_to_odooYY0.txt — shared defaults, versioned, valid for every database.

Syntax: one module per line, with a justification after #. Commas and several names per line are accepted; blank lines and full-line comments are ignored. A module without a stated reason is flagged at runtime: removing a module is a decision someone must be able to review later.

queue_job                        # blocks 12->13, trigger queue_job_notify
mgmtsystem_hazard                # not ported to 13.0
web_syncer                       # dropped upstream