Skip to content

Commit 30ea7c7

Browse files
committed
[IMP] util.rename_field
Reritew function to not use savepoints. closes #276 Signed-off-by: Christophe Simonis (chs) <[email protected]>
1 parent dd29b9f commit 30ea7c7

File tree

1 file changed

+43
-24
lines changed

1 file changed

+43
-24
lines changed

src/util/fields.py

Lines changed: 43 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,6 @@ def make_index_name(table_name, column_name):
5959
parallel_execute,
6060
pg_text2html,
6161
remove_column,
62-
savepoint,
6362
table_exists,
6463
)
6564
from .records import _remove_import_export_paths
@@ -511,49 +510,69 @@ def rename_field(cr, model, old, new, update_references=True, domain_adapter=Non
511510
# skip all inherit, they will be handled by the recursive call
512511
update_field_usage(cr, model, old, new, domain_adapter=domain_adapter, skip_inherit="*")
513512

514-
try:
515-
with savepoint(cr):
516-
cr.execute("UPDATE ir_model_fields SET name=%s WHERE model=%s AND name=%s RETURNING id", (new, model, old))
517-
[fid] = cr.fetchone() or [None]
518-
except psycopg2.IntegrityError:
513+
# search for an existing custom field.
514+
cr.execute("SELECT 1 FROM ir_model_fields WHERE model = %s AND name IN %s", [model, (old, new)])
515+
if cr.rowcount == 2:
519516
# If a field with the same name already exists for this model (e.g. due to a custom module),
520517
# rename it to avoid clashing and warn the customer
521518
custom_name = new + "_custom"
522519
rename_field(cr, model, new, custom_name, update_references, domain_adapter=None, skip_inherit=skip_inherit)
523-
cr.execute("UPDATE ir_model_fields SET name=%s WHERE model=%s AND name=%s RETURNING id", (new, model, old))
524-
[fid] = cr.fetchone() or [None]
525520
msg = (
526521
"The field %r from the model %r is now a standard Odoo field, but it already existed in the database "
527522
"(coming from a non-standard module) and thus has been renamed to %r" % (new, model, custom_name)
528523
)
529524
add_to_migration_reports(msg, "Non-standard fields")
530525

526+
cr.execute("UPDATE ir_model_fields SET name=%s WHERE model=%s AND name=%s RETURNING id", (new, model, old))
527+
[fid] = cr.fetchone() or [None]
528+
531529
if fid:
530+
# recreate the xmlids
532531
name = IMD_FIELD_PATTERN % (model.replace(".", "_"), new)
533-
# In some cases the same field may be present on ir_model_data with both the double __ and single _ name
534-
# version. To avoid conflicts (module, name) on the UPDATE below we keep only the double __ version
532+
535533
cr.execute(
536534
"""
537535
DELETE FROM ir_model_data
538-
WHERE id IN (SELECT unnest((array_agg(id ORDER BY id))[2:count(id)])
539-
FROM ir_model_data
540-
WHERE model = 'ir.model.fields'
541-
AND res_id = %s
542-
GROUP BY module)
536+
WHERE model = 'ir.model.fields'
537+
AND res_id = %s
538+
AND module != '__export__'
539+
RETURNING module
543540
""",
544541
[fid],
545542
)
546-
try:
547-
with savepoint(cr):
548-
cr.execute("UPDATE ir_model_data SET name=%s WHERE model='ir.model.fields' AND res_id=%s", [name, fid])
549-
except psycopg2.IntegrityError:
550-
# duplicate key. May happen du to conflict between
551-
# some_model.sub_id and some_model_sub.id
552-
# (before saas~11.2, where pattern changed)
553-
name = "%s_%s" % (name, fid)
554-
cr.execute("UPDATE ir_model_data SET name=%s WHERE model='ir.model.fields' AND res_id=%s", [name, fid])
543+
if cr.rowcount:
544+
modules = {mod for (mod,) in cr.fetchall()}
545+
546+
# match noupdate value with implementation which changed with commit
547+
# https://github.com/odoo/odoo/commit/a99e04dfeeef11a781b35574dd625e4007ab5654
548+
noupdate = False if version_gte("saas~11.5") else None
549+
550+
cr.execute(
551+
"""
552+
INSERT INTO ir_model_data(module, name, model, res_id, noupdate)
553+
SELECT unnest(%s), %s, 'ir.model.fields', %s, %s
554+
ON CONFLICT DO NOTHING
555+
RETURNING module
556+
""",
557+
[list(modules), name, fid, noupdate],
558+
)
559+
conflicted = modules - {mod for (mod,) in cr.fetchall()}
560+
if conflicted:
561+
# Duplicated key. May happen due to some_model.sub_id and some_model_sub.id
562+
# both leading to some_model_sub_id xmlid before saas~11.2 where the pattern
563+
# was fixed to be some_module__sub_id and some_model_sub__id respectively.
564+
on_conflict_name = "{}_{}".format(name, fid)
565+
cr.execute(
566+
"""
567+
INSERT INTO ir_model_data(module, name, model, res_id, noupdate)
568+
SELECT unnest(%s), %s, 'ir.model.fields', %s, %s
569+
""",
570+
[list(conflicted), on_conflict_name, fid, noupdate],
571+
)
572+
555573
if table_exists(cr, "ir_property"):
556574
cr.execute("UPDATE ir_property SET name=%s WHERE fields_id=%s", [new, fid])
575+
557576
# Updates custom field relation name to match the renamed standard field during upgrade.
558577
cr.execute(
559578
"""

0 commit comments

Comments
 (0)