summaryrefslogtreecommitdiff
path: root/odoo/modules/loading.py
diff options
context:
space:
mode:
authorChristophe Simonis <chs@odoo.com>2018-06-05 11:50:03 +0200
committerChristophe Simonis <chs@odoo.com>2018-06-05 11:50:03 +0200
commita002210d93031f597539e9d89e3e45fbc0320185 (patch)
treeed40a6cf551e91dc225c6f7867b1cfeda08d5915 /odoo/modules/loading.py
parent98b1fffd4e99cc8ad2862c56fbd727979c38c48b (diff)
parentc25b68f324f8d3604b33380504c3428585eb7efa (diff)
[MERGE] forward port branch 10.0 up to c25b68f324f
Diffstat (limited to 'odoo/modules/loading.py')
-rw-r--r--odoo/modules/loading.py53
1 files changed, 46 insertions, 7 deletions
diff --git a/odoo/modules/loading.py b/odoo/modules/loading.py
index 950704e45e9..750c3388064 100644
--- a/odoo/modules/loading.py
+++ b/odoo/modules/loading.py
@@ -26,7 +26,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
@@ -97,6 +98,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)
@@ -110,6 +114,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
@@ -131,9 +137,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, partial=True)
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 = {}
@@ -223,9 +240,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),))
@@ -234,7 +256,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:
@@ -248,6 +273,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):
@@ -277,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:
@@ -332,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.setup_models(cr)
@@ -398,6 +427,16 @@ def load_modules(db, force_demo=False, status=None, update_module=False):
api.Environment.reset()
return odoo.modules.registry.Registry.new(cr.dbname, force_demo, status, update_module)
+ # 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:
View = env['ir.ui.view']