diff --git a/openerp/addons/base/ir/ir_model.py b/openerp/addons/base/ir/ir_model.py index ae1ffce2fc4..579178c36cb 100644 --- a/openerp/addons/base/ir/ir_model.py +++ b/openerp/addons/base/ir/ir_model.py @@ -388,9 +388,7 @@ class ir_model_fields(osv.osv): if vals['model'].startswith('x_') and vals['name'] == 'x_name': model._rec_name = 'x_name' - if self.pool.fields_by_model is not None: - cr.execute('SELECT * FROM ir_model_fields WHERE id=%s', (res,)) - self.pool.fields_by_model.setdefault(vals['model'], []).append(cr.dictfetchone()) + self.pool.clear_manual_fields() # re-initialize model in registry model.__init__(self.pool, cr) diff --git a/openerp/models.py b/openerp/models.py index 65180419c9b..1c808ad74ba 100644 --- a/openerp/models.py +++ b/openerp/models.py @@ -694,15 +694,10 @@ class BaseModel(object): @classmethod def _init_manual_fields(cls, cr, partial): - # Check whether the query is already done - if cls.pool.fields_by_model is not None: - manual_fields = cls.pool.fields_by_model.get(cls._name, []) - else: - cr.execute('SELECT * FROM ir_model_fields WHERE model=%s AND state=%s', (cls._name, 'manual')) - manual_fields = cr.dictfetchall() + manual_fields = cls.pool.get_manual_fields(cr, cls._name) - for field in manual_fields: - if field['name'] in cls._fields: + for name, field in manual_fields.iteritems(): + if name in cls._fields: continue attrs = { 'manual': True, @@ -734,11 +729,11 @@ class BaseModel(object): attrs['comodel_name'] = field['relation'] _rel1 = field['relation'].replace('.', '_') _rel2 = field['model'].replace('.', '_') - attrs['relation'] = 'x_%s_%s_%s_rel' % (_rel1, _rel2, field['name']) + attrs['relation'] = 'x_%s_%s_%s_rel' % (_rel1, _rel2, name) attrs['column1'] = 'id1' attrs['column2'] = 'id2' attrs['domain'] = eval(field['domain']) if field['domain'] else None - cls._add_field(field['name'], Field.by_type[field['ttype']](**attrs)) + cls._add_field(name, Field.by_type[field['ttype']](**attrs)) @classmethod def _init_constraints_onchanges(cls): diff --git a/openerp/modules/loading.py b/openerp/modules/loading.py index 1694fdbccf7..9f22c2571a5 100644 --- a/openerp/modules/loading.py +++ b/openerp/modules/loading.py @@ -126,13 +126,7 @@ def load_module_graph(cr, graph, status=None, perform_checks=True, skip_modules= migrations = openerp.modules.migration.MigrationManager(cr, graph) _logger.info('loading %d modules...', len(graph)) - # Query manual fields for all models at once and save them on the registry - # so the initialization code for each model does not have to do it - # one model at a time. - registry.fields_by_model = {} - cr.execute('SELECT * FROM ir_model_fields WHERE state=%s', ('manual',)) - for field in cr.dictfetchall(): - registry.fields_by_model.setdefault(field['model'], []).append(field) + registry.clear_manual_fields() # register, instantiate and initialize models for each modules t0 = time.time() @@ -227,9 +221,7 @@ def load_module_graph(cr, graph, status=None, perform_checks=True, skip_modules= _logger.log(25, "%s modules loaded in %.2fs, %s queries", len(graph), time.time() - t0, openerp.sql_db.sql_counter - t0_sql) - # The query won't be valid for models created later (i.e. custom model - # created after the registry has been loaded), so empty its result. - registry.fields_by_model = None + registry.clear_manual_fields() cr.commit() diff --git a/openerp/modules/registry.py b/openerp/modules/registry.py index 7a377d3eafd..c6e3e2ed1d2 100644 --- a/openerp/modules/registry.py +++ b/openerp/modules/registry.py @@ -22,7 +22,7 @@ """ Models registries. """ -from collections import Mapping +from collections import Mapping, defaultdict import logging import os import threading @@ -51,7 +51,7 @@ class Registry(Mapping): self._init = True self._init_parent = {} self._assertion_report = assertion_report.assertion_report() - self.fields_by_model = None + self._fields_by_model = None # modules fully loaded (maintained during init phase by `loading` module) self._init_modules = set() @@ -114,6 +114,20 @@ class Registry(Mapping): fields.append(model_fields[fname]) return fields + def clear_manual_fields(self): + """ Invalidate the cache for manual fields. """ + self._fields_by_model = None + + def get_manual_fields(self, cr, model_name): + """ Return the manual fields (as a dict) for the given model. """ + if self._fields_by_model is None: + # Query manual fields for all models at once + self._fields_by_model = dic = defaultdict(dict) + cr.execute('SELECT * FROM ir_model_fields WHERE state=%s', ('manual',)) + for field in cr.dictfetchall(): + dic[field['model']][field['name']] = field + return self._fields_by_model[model_name] + def do_parent_store(self, cr): for o in self._init_parent: self.get(o)._parent_store_compute(cr)