From b8b05d583d6a4b331bf93268d67f18e8ef77c95a Mon Sep 17 00:00:00 2001 From: sagu-odoo Date: Mon, 3 Nov 2025 12:55:12 +0000 Subject: [PATCH] [FIX] util/models: Prevent removal manual relation table There are two model ``A`` and ``B`` and there is ``x`` many2many field in ``A`` model which is manual and relation with ``B``. Now, ``B`` model is removed. So, For that relation table is droped but the field will there and in relation model ``_unknown`` will be set https://github.com/odoo/upgrade-util/blob/25cb37389b527f442acfbb704e07769d69b11b9f/src/util/models.py#L242. As the field belongs to ``A``. So, table will be recreated from here as it checks only table is there or not https://github.com/odoo/odoo/blob/54f10b56f577ad9ed5575bd396dba7d20d22fc2e/odoo/fields.py#L4977 and after that from here env variable it have in gone and below menitoned traceback will raise. To Fix removing M2m field and added into migration report ``` Traceback (most recent call last): File "/home/odoo/src/odoo/19.0/odoo/service/server.py", line 1509, in preload_registries registry = Registry.new(dbname, update_module=update_module, install_modules=config['init'], upgrade_modules=config['update'], reinit_modules=config['reinit']) File "/home/odoo/src/odoo/19.0/odoo/tools/func.py", line 88, in locked return func(inst, *args, **kwargs) File "/home/odoo/src/odoo/19.0/odoo/orm/registry.py", line 185, in new load_modules( File "/home/odoo/src/odoo/19.0/odoo/modules/loading.py", line 580, in load_modules model._register_hook() File "/tmp/tmpkw62chtg/migrations/base/0.0.0/pre-models-ir_model_relation.py", line 49, in _register_hook raise util.MigrationError("The following m2m relations have respawn:\n%s" % back_m2m) odoo.upgrade.util.exceptions.UpgradeError: The following m2m relations have respawn: - x_res_partner_uom_category_rel via uom.category ``` upg-3191893 opw-5175564 --- src/util/models.py | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/util/models.py b/src/util/models.py index c92d42a0b..7deefbe52 100644 --- a/src/util/models.py +++ b/src/util/models.py @@ -193,6 +193,30 @@ def remove_model(cr, model, drop_table=True, ignore_m2m=()): if ignore_m2m != "*": tables = get_m2m_tables(cr, table_of_model(cr, model)) ignore = set(ignore_m2m) + if tables: + cr.execute( + """ + SELECT name, model + FROM ir_model_fields + WHERE relation_table IN %s + AND state = 'manual' + """, + [tuple(tables)], + ) + + if cr.rowcount: + affected_fields = cr.fetchall() + for field, field_model in affected_fields: + remove_field(cr, field_model, field, drop_column=False) + msg = "The following fields have been removed because their related model {} ({}) was removed:\n{}".format( + mod_label, model, "\n".join(" - field {} of model {}".format(*r) for r in affected_fields) + ) + add_to_migration_reports( + message=msg, + category="Removed Fields", + format="md", + ) + for table_name in tables: if table_name in ignore: _logger.info("remove_model(%r): m2m table %r explicitly ignored", model, table_name)