[FIX] base: restore deletion of dependencies on field removal
odoo/odoo#111651 improved and optimised triggers but dropped the in-place cleanup of field dependencies. As a consequence, during module uninstallation if a stored computed field is removed (because it's part of a module being uninstalled), and one of its dependencies is subsequently altered (e.g. it's itself removed, or written to) the second update will break as the query trying to find out which dependent records to update will error, either because of trying to select / filter on a missing column, or because of trying to fetch in a missing table. The simplest examples of this issue are computed fields with a dependency on `ir.model`: - In `calendar`, `calendar.event.res_model` is a related on `res_model_id.model`, this prevents the removal of *any* `ir.model` record if it gets uninstalled. As a result the `calendar.attendee` and `calendar.event` tables don't get removed (just emptied of all their non-automatic fields), their records remain as well, and when the non-automatic fields get re-added during installation re-instating the NOT NULL constraints fails, breaking the uninstall/reinstall test. - In `payment`, `payment.provider.module_state` is a related on `module_id.state`, this breaks *during* uninstallation, as after `module_uninstall` first calls `_module_data_uninstall` which removes the field, then it *updates the modules being uninstalled* (sets their state), which tries to find out which `payment.provider`'s `module_state` is should update, which breaks because the `module_id` column has been removed. This second one was worked around in odoo/odoo#118900, by marking modules as uninstalled before actually gutting them, but as it turns out the "actual" fix is needed anyway. So revert the workaround, and actually fix the issue. closes odoo/odoo#119130 X-original-commit: 48a420efcf7c7b46416bab006003553cc9d23846 Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
This commit is contained in:
@@ -483,9 +483,9 @@ class Module(models.Model):
|
||||
tables, columns, constraints, etc.
|
||||
"""
|
||||
modules_to_remove = self.mapped('name')
|
||||
self.env['ir.model.data']._module_data_uninstall(modules_to_remove)
|
||||
# we deactivate prefetching to not try to read a column that has been deleted
|
||||
self.with_context(prefetch_fields=False).write({'state': 'uninstalled', 'latest_version': False})
|
||||
self.env['ir.model.data']._module_data_uninstall(modules_to_remove)
|
||||
return True
|
||||
|
||||
def _remove_copied_views(self):
|
||||
|
||||
@@ -359,6 +359,11 @@ class Registry(Mapping):
|
||||
|
||||
def _discard_fields(self, fields: list):
|
||||
""" Discard the given fields from the registry's internal data structures. """
|
||||
for f in fields:
|
||||
# tests usually don't reload the registry, so when they create
|
||||
# custom fields those may not have the entire dependency setup, and
|
||||
# may be missing from these maps
|
||||
self.field_depends.pop(f, None)
|
||||
|
||||
# discard fields from field triggers
|
||||
self.__dict__.pop('_field_triggers', None)
|
||||
|
||||
Reference in New Issue
Block a user