From 133d8595dd7a97bcc5354c3732ae5fbe1e487155 Mon Sep 17 00:00:00 2001 From: Alvaro Fuentes Date: Mon, 14 Apr 2025 11:22:08 +0200 Subject: [PATCH] [IMP] util/records: skip replace if all ids are the same If all ids are the same and we are replacing in the same model we currently cause an error. This is not necessary and could lead to false errors if the list of mapping ids is correctly the same. For example sometimes we transform a model A into model B by updating metadata. Then we insert into B's table, and finally perform a replace of references from A's table to B's table. This would fail if the ids are the same. This case will happen with a high probability if there is only one A record with id=1 since the single B record would get id=1 as well. Example logs after the patch: ``` 2025-04-14 07:28:32,883 42811 WARNING test_16 odoo.upgrade.util.records: Replace references in model `res.country`, ignoring same-id mapping `{1: 1, 2: 2}` 2025-04-14 07:28:32,883 42811 WARNING test_16 odoo.upgrade.util.records: Nothing to replace in model `res.country`, ignoring empty mapping ``` --- src/base/tests/test_util.py | 5 +++++ src/util/records.py | 3 +++ 2 files changed, 8 insertions(+) diff --git a/src/base/tests/test_util.py b/src/base/tests/test_util.py index ce0bb1abf..67d2a8afd 100644 --- a/src/base/tests/test_util.py +++ b/src/base/tests/test_util.py @@ -1449,6 +1449,11 @@ def test_replace_record_references_batch__uniqueness(self): [count] = self.env.cr.fetchone() self.assertEqual(count, 1) + @mute_logger("odoo.upgrade.util.records") + def test_replace_record_references_batch__idem_mapping(self): + # This logs a warning but shouldn't fail + util.replace_record_references_batch(self.env.cr, {1: 1, 2: 2}, "res.country") + def _prepare_test_delete_unused(self): def create_cat(): name = f"test_{uuid.uuid4().hex}" diff --git a/src/util/records.py b/src/util/records.py index b9127b838..7b748cfb9 100644 --- a/src/util/records.py +++ b/src/util/records.py @@ -1469,6 +1469,9 @@ def replace_record_references_batch(cr, id_mapping, model_src, model_dst=None, r if same_ids: _logger.warning("Replace references in model `%s`, ignoring same-id mapping `%s`", model_src, same_ids) id_mapping = {k: v for k, v in id_mapping.items() if k != v} + if not id_mapping: + _logger.warning("Nothing to replace in model `%s`, ignoring empty mapping", model_src) + return assert id_mapping assert all(isinstance(v, int) and isinstance(k, int) for k, v in id_mapping.items())