summaryrefslogtreecommitdiff
path: root/odoo/modules
diff options
context:
space:
mode:
Diffstat (limited to 'odoo/modules')
-rw-r--r--odoo/modules/loading.py52
-rw-r--r--odoo/modules/registry.py2
2 files changed, 47 insertions, 7 deletions
diff --git a/odoo/modules/loading.py b/odoo/modules/loading.py
index 4dda572fb13..b9f4e2fdc7b 100644
--- a/odoo/modules/loading.py
+++ b/odoo/modules/loading.py
@@ -25,7 +25,8 @@ _logger = logging.getLogger(__name__)
_test_logger = logging.getLogger('odoo.tests')
-def load_module_graph(cr, graph, status=None, perform_checks=True, skip_modules=None, report=None):
+def load_module_graph(cr, graph, status=None, perform_checks=True,
+ skip_modules=None, report=None, models_to_check=None):
"""Migrates+Updates or Installs all module nodes from ``graph``
:param graph: graph of module nodes to load
:param status: deprecated parameter, unused, left to avoid changing signature in 8.0
@@ -93,6 +94,9 @@ def load_module_graph(cr, graph, status=None, perform_checks=True, skip_modules=
if kind in ('demo', 'test'):
threading.currentThread().testing = False
+ if models_to_check is None:
+ models_to_check = set()
+
processed_modules = []
loaded_modules = []
registry = odoo.registry(cr.dbname)
@@ -106,6 +110,8 @@ def load_module_graph(cr, graph, status=None, perform_checks=True, skip_modules=
t0 = time.time()
t0_sql = odoo.sql_db.sql_counter
+ models_updated = set()
+
for index, package in enumerate(graph, 1):
module_name = package.name
module_id = package.id
@@ -127,10 +133,20 @@ def load_module_graph(cr, graph, status=None, perform_checks=True, skip_modules=
model_names = registry.load(cr, package)
loaded_modules.append(package.name)
- if hasattr(package, 'init') or hasattr(package, 'update') or package.state in ('to install', 'to upgrade'):
+ if (hasattr(package, 'init') or hasattr(package, 'update')
+ or package.state in ('to install', 'to upgrade')):
+ models_updated |= set(model_names)
+ models_to_check -= set(model_names)
registry.setup_models(cr)
registry.init_models(cr, model_names, {'module': package.name})
cr.commit()
+ elif package.state != 'to remove':
+ # The current module has simply been loaded. The models extended by this module
+ # and for which we updated the schema, must have their schema checked again.
+ # This is because the extension may have changed the model,
+ # e.g. adding required=True to an existing field, but the schema has not been
+ # updated by this module because it's not marked as 'to upgrade/to install'.
+ models_to_check |= set(model_names) & models_updated
idref = {}
@@ -225,9 +241,14 @@ def _check_module_names(cr, module_names):
incorrect_names = mod_names.difference([x['name'] for x in cr.dictfetchall()])
_logger.warning('invalid module names, ignored: %s', ", ".join(incorrect_names))
-def load_marked_modules(cr, graph, states, force, progressdict, report, loaded_modules, perform_checks):
+def load_marked_modules(cr, graph, states, force, progressdict, report,
+ loaded_modules, perform_checks, models_to_check=None):
"""Loads modules marked with ``states``, adding them to ``graph`` and
``loaded_modules`` and returns a list of installed/upgraded modules."""
+
+ if models_to_check is None:
+ models_to_check = set()
+
processed_modules = []
while True:
cr.execute("SELECT name from ir_module_module WHERE state IN %s" ,(tuple(states),))
@@ -236,7 +257,10 @@ def load_marked_modules(cr, graph, states, force, progressdict, report, loaded_m
break
graph.add_modules(cr, module_list, force)
_logger.debug('Updating graph with %d more modules', len(module_list))
- loaded, processed = load_module_graph(cr, graph, progressdict, report=report, skip_modules=loaded_modules, perform_checks=perform_checks)
+ loaded, processed = load_module_graph(
+ cr, graph, progressdict, report=report, skip_modules=loaded_modules,
+ perform_checks=perform_checks, models_to_check=models_to_check
+ )
processed_modules.extend(processed)
loaded_modules.extend(loaded)
if not processed:
@@ -250,6 +274,8 @@ def load_modules(db, force_demo=False, status=None, update_module=False):
if force_demo:
force.append('demo')
+ models_to_check = set()
+
cr = db.cursor()
try:
if not odoo.modules.db.is_initialized(cr):
@@ -278,7 +304,9 @@ def load_modules(db, force_demo=False, status=None, update_module=False):
# processed_modules: for cleanup step after install
# loaded_modules: to avoid double loading
report = registry._assertion_report
- loaded_modules, processed_modules = load_module_graph(cr, graph, status, perform_checks=update_module, report=report)
+ loaded_modules, processed_modules = load_module_graph(
+ cr, graph, status, perform_checks=update_module,
+ report=report, models_to_check=models_to_check)
load_lang = tools.config.pop('load_language')
if load_lang or update_module:
@@ -333,11 +361,11 @@ def load_modules(db, force_demo=False, status=None, update_module=False):
previously_processed = len(processed_modules)
processed_modules += load_marked_modules(cr, graph,
['installed', 'to upgrade', 'to remove'],
- force, status, report, loaded_modules, update_module)
+ force, status, report, loaded_modules, update_module, models_to_check)
if update_module:
processed_modules += load_marked_modules(cr, graph,
['to install'], force, status, report,
- loaded_modules, update_module)
+ loaded_modules, update_module, models_to_check)
registry.loaded = True
registry.setup_models(cr)
@@ -407,6 +435,16 @@ def load_modules(db, force_demo=False, status=None, update_module=False):
cr.commit()
return registry
+ # STEP 5.5: Verify extended fields on every model
+ # This will fix the schema of all models in a situation such as:
+ # - module A is loaded and defines model M;
+ # - module B is installed/upgraded and extends model M;
+ # - module C is loaded and extends model M;
+ # - module B and C depend on A but not on each other;
+ # The changes introduced by module C are not taken into account by the upgrade of B.
+ if models_to_check:
+ registry.init_models(cr, list(models_to_check), {'models_to_check': True})
+
# STEP 6: verify custom views on every model
if update_module:
env = api.Environment(cr, SUPERUSER_ID, {})
diff --git a/odoo/modules/registry.py b/odoo/modules/registry.py
index c7d8711287b..3115470adeb 100644
--- a/odoo/modules/registry.py
+++ b/odoo/modules/registry.py
@@ -298,6 +298,8 @@ class Registry(Mapping):
"""
if 'module' in context:
_logger.info('module %s: creating or updating database tables', context['module'])
+ elif context.get('models_to_check', False):
+ _logger.info("verifying fields for every extended model")
env = odoo.api.Environment(cr, SUPERUSER_ID, context)
models = [env[model_name] for model_name in model_names]