[FIX] orm: don't log errors on constraint failure unless necessary
Given an scenario in which a field F of model M is defined in module X as `required=True` and is extended by another module Y as `required=False` in a database with data not satisfying the original constraint: During an upgrade of base the original constraint will be re-applied on the data (and fail) even though it is no longer necessary because module Y relaxes the NOT NULL constraint. This failure in and of itself is non-blocking, the upgrade will go through but an error and a warning are logged anyway which are not problematic either except in the case of automated testing infrastructure (such as runbot), because of this it would be best if these errors would not be logged at all unless we're 100% sure that the constraint that was applied is not relaxed downstream. With this commit, the `finalize_constraints` method will verify that the constraint is applicable (field is required) before re-applying the NOT NULL constraint. opw-2269220 closes odoo/odoo#53529 X-original-commit: f09f4826fbdd1a547503c51a3cfad71285312c49 Signed-off-by: Raphael Collet (rco) <rco@openerp.com>
This commit is contained in:
committed by
Raphael Collet
parent
195c7e83fe
commit
ce4fcebbbb
+11
-1
@@ -836,7 +836,7 @@ class Field(MetaField('DummyField', (object,), {})):
|
||||
def add_not_null():
|
||||
# flush values before adding NOT NULL constraint
|
||||
model.flush([self.name])
|
||||
model.pool.post_constraint(sql.set_not_null, model._cr, model._table, self.name)
|
||||
model.pool.post_constraint(apply_required, model, self.name)
|
||||
|
||||
elif not self.required and has_notnull:
|
||||
sql.drop_not_null(model._cr, model._table, self.name)
|
||||
@@ -3702,6 +3702,16 @@ def prefetch_x2many_ids(record, field):
|
||||
return unique(id_ for ids in ids_list for id_ in ids)
|
||||
|
||||
|
||||
def apply_required(model, field_name):
|
||||
""" Set a NOT NULL constraint on the given field, if necessary. """
|
||||
# At the time this function is called, the model's _fields may have been reset, although
|
||||
# the model's class is still the same. Retrieve the field to see whether the NOT NULL
|
||||
# constraint still applies
|
||||
field = model._fields[field_name]
|
||||
if field.store and field.required:
|
||||
sql.set_not_null(model.env.cr, model._table, field_name)
|
||||
|
||||
|
||||
# imported here to avoid dependency cycle issues
|
||||
from .exceptions import AccessError, MissingError, UserError
|
||||
from .models import check_pg_name, BaseModel, NewId, IdType
|
||||
|
||||
Reference in New Issue
Block a user