+ _schema.debug("Table '%s': added foreign key '%s' with definition=REFERENCES \"%s\" ON DELETE %s",
+ source_table, source_field, dest_model._table, ondelete)
+
+ def _drop_constraint(self, cr, source_table, constraint_name):
+ cr.execute("ALTER TABLE %s DROP CONSTRAINT %s" % (source_table,constraint_name))
+
+ def _m2o_fix_foreign_key(self, cr, source_table, source_field, dest_model, ondelete):
+ # Find FK constraint(s) currently established for the m2o field,
+ # and see whether they are stale or not
+ cr.execute("""SELECT confdeltype as ondelete_rule, conname as constraint_name,
+ cl2.relname as foreign_table
+ FROM pg_constraint as con, pg_class as cl1, pg_class as cl2,
+ pg_attribute as att1, pg_attribute as att2
+ WHERE con.conrelid = cl1.oid
+ AND cl1.relname = %s
+ AND con.confrelid = cl2.oid
+ AND array_lower(con.conkey, 1) = 1
+ AND con.conkey[1] = att1.attnum
+ AND att1.attrelid = cl1.oid
+ AND att1.attname = %s
+ AND array_lower(con.confkey, 1) = 1
+ AND con.confkey[1] = att2.attnum
+ AND att2.attrelid = cl2.oid
+ AND att2.attname = %s
+ AND con.contype = 'f'""", (source_table, source_field, 'id'))
+ constraints = cr.dictfetchall()
+ if constraints:
+ if len(constraints) == 1:
+ # Is it the right constraint?
+ cons, = constraints
+ if cons['ondelete_rule'] != POSTGRES_CONFDELTYPES.get((ondelete or 'set null').upper(), 'a')\
+ or cons['foreign_table'] != dest_model._table:
+ _schema.debug("Table '%s': dropping obsolete FK constraint: '%s'",
+ source_table, cons['constraint_name'])
+ self._drop_constraint(cr, source_table, cons['constraint_name'])
+ self._m2o_add_foreign_key_checked(source_field, dest_model, ondelete)
+ # else it's all good, nothing to do!
+ else:
+ # Multiple FKs found for the same field, drop them all, and re-create
+ for cons in constraints:
+ _schema.debug("Table '%s': dropping duplicate FK constraints: '%s'",
+ source_table, cons['constraint_name'])
+ self._drop_constraint(cr, source_table, cons['constraint_name'])
+ self._m2o_add_foreign_key_checked(source_field, dest_model, ondelete)
+
+