odoo/upgrade-util#243

Created by Upgrade, Alvaro Fuentes Suarez (afu)
Merged at 0cd78cb408872331fa48b4886264586c250167be

Statuses:

label
odoo-dev:master-fix_rrr2-afu
head
e2dea0ea36010f41b82d094af54a8fadf46ae98b
merged
2 months ago by Upgrade, Christophe Simonis (chs)
odoo/upgrade-util
master #243

[FIX] util/records: deduplicate before batch update

When updating record references we need to dedup uniq indexes. In the case of inderect references the case when two old references become the same new reference was missing.

Example to trigger the issue

test_15=> select * from mail_followers where res_model='res.partner.bank'
+----+------------------+--------+------------+
| id | res_model        | res_id | partner_id |
|----+------------------+--------+------------|
| 5  | res.partner.bank | 2      | 3          |
| 7  | res.partner.bank | 3      | 3          |
+----+------------------+--------+------------+
test_15=> select id,sanitized_acc_number,partner_id,company_id from res_partner_bank
+----+----------------------+------------+------------+
| id | sanitized_acc_number | partner_id | company_id |
|----+----------------------+------------+------------|
| 1  | 1                    | 3          | 1          |
| 2  | 1                    | 3          | 2          |
| 3  | 1                    | 3          | 3          |
+----+----------------------+------------+------------+

In such case the record replacer will replace references to the partner bank as in the mapping {2:1, 3:1}. But this causes an error

2025-03-07 17:12:12,145 502959 ERROR test_15_16 odoo.sql_db: bad query:

            UPDATE "mail_followers" t
               SET "res_model" = 'res.partner.bank'
                   , "res_id" = _upgrade_rrr.new
              FROM _upgrade_rrr
             WHERE "res_model"='res.partner.bank'
               AND _upgrade_rrr.old = res_id

                    AND
                        NOT EXISTS(SELECT 1 FROM mail_followers WHERE "res_model" = 'res.partner.bank' AND "res_id" = _upgrade_rrr.new AND "partner_id"=t."partner_id")
                    ;
                DELETE FROM mail_followers USING _upgrade_rrr WHERE "res_model"='res.partner.bank' AND res_id = _upgrade_rrr.old;

ERROR: duplicate key value violates unique constraint "mail_followers_mail_followers_res_partner_res_model_id_uniq"
DETAIL:  Key (res_model, res_id, partner_id)=(res.partner.bank, 1, 3) already exists.