@@ -642,18 +642,44 @@ def view_exists(cr, view):
642642 return bool (cr .rowcount )
643643
644644
645- def remove_constraint (cr , table , name , cascade = False ):
645+ def remove_constraint (cr , table , name , cascade = False , warn = True ):
646+ """
647+ Remove a table constraint.
648+
649+ This function removes the constraint `name` from `table`. It also removes records from
650+ `ir_model_constraint` and its xml_ids. It logs not found constraints.
651+
652+ .. note::
653+
654+ If there is no constraint `name`, this function will attempt to remove
655+ ``{table}_{name}``, the latter is the default name the ORM uses for constraints
656+ created from `_sql_constraints`.
657+
658+ :param str table: table from where to remove the constraint
659+ :param str name: name of the constraint to remove
660+ :param bool cascade: cascade the constraint removal
661+ :param bool warn: use warning level when logging not found constraints, otherwise use
662+ info level
663+ :return: whether the constraint was removed
664+ :rtype: bool
665+ """
646666 _validate_table (table )
667+ log = _logger .warning if warn else _logger .info
647668 cascade = "CASCADE" if cascade else ""
648669 cr .execute ('ALTER TABLE "{}" DROP CONSTRAINT IF EXISTS "{}" {}' .format (table , name , cascade ))
649- # small exception: odoo specific action.
650- # needs to be kept here to avoid resurive imports.
651- # a solution would be to not do it now but adds an `end-` script that remove the invalid entries
652- # from the `ir_model_constraint` table
670+ # Exceptionally remove Odoo records, even if we are in PG land on this file. This is somehow
671+ # valid because ir.model.constraint are ORM low-level objects that relate directly to table
672+ # constraints.
653673 cr .execute ("DELETE FROM ir_model_constraint WHERE name = %s RETURNING id" , [name ])
654674 if cr .rowcount :
655675 ids = tuple (c for (c ,) in cr .fetchall ())
656676 cr .execute ("DELETE FROM ir_model_data WHERE model = 'ir.model.constraint' AND res_id IN %s" , [ids ])
677+ return True
678+ if name .startswith (table + "_" ):
679+ log ("%r not found in ir_model_constraint, table=%r" , name , table )
680+ return False
681+ log ("%r not found in ir_model_constraint, attempting to remove with table %r prefix" , name , table )
682+ return remove_constraint (cr , table , "{}_{}" .format (table , name ), cascade , warn )
657683
658684
659685def get_fk (cr , table , quote_ident = True ):
@@ -728,7 +754,7 @@ class IndexInfo(collections.namedtuple("IndexInfo", "name on isunique isconstrai
728754
729755 def drop (self , cr ):
730756 if self .isconstraint :
731- remove_constraint (cr , self .on , self .name )
757+ remove_constraint (cr , self .on , self .name , warn = False )
732758 else :
733759 cr .execute ('DROP INDEX "%s"' % self .name )
734760
@@ -1064,7 +1090,7 @@ def rename_table(cr, old_table, new_table, remove_constraints=True):
10641090 )
10651091 for (const ,) in cr .fetchall ():
10661092 _logger .info ("Dropping constraint %s on table %s" , const , new_table )
1067- remove_constraint (cr , new_table , const )
1093+ remove_constraint (cr , new_table , const , warn = False )
10681094
10691095 # rename fkeys
10701096 cr .execute (
0 commit comments