@@ -59,7 +59,6 @@ def make_index_name(table_name, column_name):
59
59
parallel_execute ,
60
60
pg_text2html ,
61
61
remove_column ,
62
- savepoint ,
63
62
table_exists ,
64
63
)
65
64
from .records import _remove_import_export_paths
@@ -511,49 +510,69 @@ def rename_field(cr, model, old, new, update_references=True, domain_adapter=Non
511
510
# skip all inherit, they will be handled by the recursive call
512
511
update_field_usage (cr , model , old , new , domain_adapter = domain_adapter , skip_inherit = "*" )
513
512
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 :
519
516
# If a field with the same name already exists for this model (e.g. due to a custom module),
520
517
# rename it to avoid clashing and warn the customer
521
518
custom_name = new + "_custom"
522
519
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 ]
525
520
msg = (
526
521
"The field %r from the model %r is now a standard Odoo field, but it already existed in the database "
527
522
"(coming from a non-standard module) and thus has been renamed to %r" % (new , model , custom_name )
528
523
)
529
524
add_to_migration_reports (msg , "Non-standard fields" )
530
525
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
+
531
529
if fid :
530
+ # recreate the xmlids
532
531
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
+
535
533
cr .execute (
536
534
"""
537
535
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
543
540
""" ,
544
541
[fid ],
545
542
)
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
+
555
573
if table_exists (cr , "ir_property" ):
556
574
cr .execute ("UPDATE ir_property SET name=%s WHERE fields_id=%s" , [new , fid ])
575
+
557
576
# Updates custom field relation name to match the renamed standard field during upgrade.
558
577
cr .execute (
559
578
"""
0 commit comments