diff --git a/src/util/models.py b/src/util/models.py index 9f68def22..996cd4ebc 100644 --- a/src/util/models.py +++ b/src/util/models.py @@ -58,7 +58,7 @@ def _unknown_model_id(cr): return cr.fetchone()[0] -def remove_model(cr, model, drop_table=True, ignore_m2m=()): +def remove_model(cr, model, drop_table=True, ignore_m2m=(), remove_inherits=False): """ Remove a model and its references from the database. @@ -67,6 +67,7 @@ def remove_model(cr, model, drop_table=True, ignore_m2m=()): :param str model: name of the model to remove :param bool drop_table: whether to drop the table of this model + :param bool remove_inherits: whether to also clean inherits of ``model`` :param list(str) or str ignore_m2m: list of m2m tables to ignore - not removed, use `"*"` to ignore (keep) all m2m tables """ @@ -162,6 +163,16 @@ def remove_model(cr, model, drop_table=True, ignore_m2m=()): _remove_import_export_paths(cr, model) + for inh in for_each_inherit(cr, model): + if remove_inherits: + remove_inherit_from_model(cr, inh.model, model) + else: + _logger.warning( + "Model %r is being removed, to also remove its inherit from %r set the `remove_inherits` flag in `remove_model()`.", + model, + inh.model, + ) + _rm_refs(cr, model) cr.execute( diff --git a/src/util/modules.py b/src/util/modules.py index 5b1555985..93d2afb6e 100644 --- a/src/util/modules.py +++ b/src/util/modules.py @@ -120,11 +120,12 @@ def module_installed(cr, module): return modules_installed(cr, module) -def uninstall_module(cr, module): +def uninstall_module(cr, module, remove_model_inherits=False): """ Uninstall and remove all records owned by a module. :param str module: name of the module to uninstall + :param bool remove_model_inherits: whether to remove inherits of the module's models """ cr.execute("SELECT id FROM ir_module_module WHERE name=%s", (module,)) (mod_id,) = cr.fetchone() or [None] @@ -233,13 +234,13 @@ def uninstall_module(cr, module): if model_ids: cr.execute("SELECT model FROM ir_model WHERE id IN %s", [tuple(model_ids)]) for (model,) in cr.fetchall(): - delete_model(cr, model) + delete_model(cr, model, remove_inherits=remove_model_inherits) if field_ids: cr.execute("SELECT model, name FROM ir_model_fields WHERE id IN %s", [tuple(field_ids)]) for model, name in cr.fetchall(): if name == "id": - delete_model(cr, model) + delete_model(cr, model, remove_inherits=remove_model_inherits) else: remove_field(cr, model, name) @@ -284,7 +285,7 @@ def uninstall_theme(cr, theme, base_theme=None): uninstall_module(cr, theme) -def remove_module(cr, module): +def remove_module(cr, module, remove_model_inherits=False): """ Completely remove a module. @@ -292,6 +293,7 @@ def remove_module(cr, module): the module - no trace of it is left in the database. :param str module: name of the module to remove + :param bool remove_model_inherits: whether to remove inherits of the module's models .. warning:: Since this function removes *all* data associated to the module. Ensure to @@ -301,7 +303,7 @@ def remove_module(cr, module): # module need to be currently installed and running as deletions # are made using orm. - uninstall_module(cr, module) + uninstall_module(cr, module, remove_model_inherits=remove_model_inherits) cr.execute("DELETE FROM ir_module_module_dependency WHERE name=%s", (module,)) cr.execute("DELETE FROM ir_module_module WHERE name=%s RETURNING id", (module,)) if cr.rowcount: