@@ -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)
6564from .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