_schema.debug("Table '%s': column '%s': dropped NOT NULL constraint",
self._table, column['attname'])
- def _save_constraint(self, cr, constraint_name, type):
+ def _save_constraint(self, cr, constraint_name, type, definition):
"""
Record the creation of a constraint for this model, to make it possible
to delete it later when the module is uninstalled. Type can be either
return
assert type in ('f', 'u')
cr.execute("""
- SELECT 1 FROM ir_model_constraint, ir_module_module
+ SELECT type, definition FROM ir_model_constraint, ir_module_module
WHERE ir_model_constraint.module=ir_module_module.id
AND ir_model_constraint.name=%s
AND ir_module_module.name=%s
""", (constraint_name, self._module))
- if not cr.rowcount:
+ constraints = cr.dictfetchone()
+ if not constraints:
cr.execute("""
INSERT INTO ir_model_constraint
- (name, date_init, date_update, module, model, type)
+ (name, date_init, date_update, module, model, type, definition)
VALUES (%s, now() AT TIME ZONE 'UTC', now() AT TIME ZONE 'UTC',
(SELECT id FROM ir_module_module WHERE name=%s),
- (SELECT id FROM ir_model WHERE model=%s), %s)""",
- (constraint_name, self._module, self._name, type))
+ (SELECT id FROM ir_model WHERE model=%s), %s, %s)""",
+ (constraint_name, self._module, self._name, type, definition))
+ elif constraints['type'] != type or (definition and constraints['definition'] != definition):
+ cr.execute("""
+ UPDATE ir_model_constraint
+ SET date_update=now() AT TIME ZONE 'UTC', type=%s, definition=%s
+ WHERE name=%s AND module = (SELECT id FROM ir_module_module WHERE name=%s)""",
+ (type, definition, constraint_name, self._module))
def _save_relation_table(self, cr, relation_table):
"""
""" Create the foreign keys recorded by _auto_init. """
for t, k, r, d in self._foreign_keys:
cr.execute('ALTER TABLE "%s" ADD FOREIGN KEY ("%s") REFERENCES "%s" ON DELETE %s' % (t, k, r, d))
- self._save_constraint(cr, "%s_%s_fkey" % (t, k), 'f')
+ self._save_constraint(cr, "%s_%s_fkey" % (t, k), 'f', False)
cr.commit()
del self._foreign_keys
for (key, con, _) in self._sql_constraints:
conname = '%s_%s' % (self._table, key)
- self._save_constraint(cr, conname, 'u')
- cr.execute("SELECT conname, pg_catalog.pg_get_constraintdef(oid, true) as condef FROM pg_constraint where conname=%s", (conname,))
- existing_constraints = cr.dictfetchall()
+ # using 1 to get result if no imc but one pgc
+ cr.execute("""SELECT definition, 1
+ FROM ir_model_constraint imc
+ RIGHT JOIN pg_constraint pgc
+ ON (pgc.conname = imc.name)
+ WHERE pgc.conname=%s
+ """, (conname, ))
+ existing_constraints = cr.dictfetchone()
sql_actions = {
'drop': {
'execute': False,
# constraint does not exists:
sql_actions['add']['execute'] = True
sql_actions['add']['msg_err'] = sql_actions['add']['msg_err'] % (sql_actions['add']['query'], )
- elif unify_cons_text(con) not in [unify_cons_text(item['condef']) for item in existing_constraints]:
+ elif unify_cons_text(con) != existing_constraints['definition']:
# constraint exists but its definition has changed:
sql_actions['drop']['execute'] = True
- sql_actions['drop']['msg_ok'] = sql_actions['drop']['msg_ok'] % (existing_constraints[0]['condef'].lower(), )
+ sql_actions['drop']['msg_ok'] = sql_actions['drop']['msg_ok'] % (existing_constraints['definition'] or '', )
sql_actions['add']['execute'] = True
sql_actions['add']['msg_err'] = sql_actions['add']['msg_err'] % (sql_actions['add']['query'], )
# we need to add the constraint:
+ self._save_constraint(cr, conname, 'u', unify_cons_text(con))
sql_actions = [item for item in sql_actions.values()]
sql_actions.sort(key=lambda x: x['order'])
for sql_action in [action for action in sql_actions if action['execute']]: