[IMP] models: speedup registry loading (35% less time)
The field setup on models is improved: only fields are determined when building the model's class; the final _columns is computed from the fields once they are set up.
This commit is contained in:
parent
37e85a1e35
commit
2f06adde9c
|
@ -481,11 +481,7 @@ class BaseModel(object):
|
||||||
# basic setup of field
|
# basic setup of field
|
||||||
field.set_class_name(cls, name)
|
field.set_class_name(cls, name)
|
||||||
|
|
||||||
if field.store or field.column:
|
# cls._columns will be updated once fields are set up
|
||||||
cls._columns[name] = field.to_column()
|
|
||||||
else:
|
|
||||||
# remove potential column that may be overridden by field
|
|
||||||
cls._columns.pop(name, None)
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def _pop_field(cls, name):
|
def _pop_field(cls, name):
|
||||||
|
@ -605,13 +601,6 @@ class BaseModel(object):
|
||||||
# inferred metadata; use its ancestor instead
|
# inferred metadata; use its ancestor instead
|
||||||
parent_class = type(parent_model).__base__
|
parent_class = type(parent_model).__base__
|
||||||
|
|
||||||
# don't inherit custom fields
|
|
||||||
columns = dict((key, val)
|
|
||||||
for key, val in parent_class._columns.iteritems()
|
|
||||||
if not val.manual
|
|
||||||
)
|
|
||||||
columns.update(cls._columns)
|
|
||||||
|
|
||||||
inherits = dict(parent_class._inherits)
|
inherits = dict(parent_class._inherits)
|
||||||
inherits.update(cls._inherits)
|
inherits.update(cls._inherits)
|
||||||
|
|
||||||
|
@ -635,7 +624,6 @@ class BaseModel(object):
|
||||||
attrs = {
|
attrs = {
|
||||||
'_name': name,
|
'_name': name,
|
||||||
'_register': False,
|
'_register': False,
|
||||||
'_columns': columns,
|
|
||||||
'_inherits': inherits,
|
'_inherits': inherits,
|
||||||
'_depends': depends,
|
'_depends': depends,
|
||||||
'_constraints': constraints,
|
'_constraints': constraints,
|
||||||
|
@ -648,7 +636,7 @@ class BaseModel(object):
|
||||||
attrs = {
|
attrs = {
|
||||||
'_name': name,
|
'_name': name,
|
||||||
'_register': False,
|
'_register': False,
|
||||||
'_columns': dict(cls._columns),
|
'_columns': {}, # filled by _setup_fields()
|
||||||
'_defaults': {}, # filled by Field._determine_default()
|
'_defaults': {}, # filled by Field._determine_default()
|
||||||
'_inherits': dict(cls._inherits),
|
'_inherits': dict(cls._inherits),
|
||||||
'_depends': dict(cls._depends),
|
'_depends': dict(cls._depends),
|
||||||
|
@ -2874,18 +2862,12 @@ class BaseModel(object):
|
||||||
#
|
#
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def _inherits_reload(cls):
|
def _init_inherited_fields(cls):
|
||||||
""" Recompute the _inherit_fields mapping, and inherited fields. """
|
""" Determine inherited fields. """
|
||||||
struct = {}
|
# determine candidate inherited fields
|
||||||
fields = {}
|
fields = {}
|
||||||
for parent_model, parent_field in cls._inherits.iteritems():
|
for parent_model, parent_field in cls._inherits.iteritems():
|
||||||
parent = cls.pool[parent_model]
|
parent = cls.pool[parent_model]
|
||||||
# old-api struct for _inherit_fields
|
|
||||||
for name, column in parent._columns.iteritems():
|
|
||||||
struct[name] = (parent_model, parent_field, column, parent_model)
|
|
||||||
for name, source in parent._inherit_fields.iteritems():
|
|
||||||
struct[name] = (parent_model, parent_field, source[2], source[3])
|
|
||||||
# new-api fields for _fields
|
|
||||||
for name, field in parent._fields.iteritems():
|
for name, field in parent._fields.iteritems():
|
||||||
fields[name] = field.new(
|
fields[name] = field.new(
|
||||||
inherited=True,
|
inherited=True,
|
||||||
|
@ -2893,15 +2875,25 @@ class BaseModel(object):
|
||||||
related_sudo=False,
|
related_sudo=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
# old-api stuff
|
|
||||||
cls._inherit_fields = struct
|
|
||||||
cls._all_columns = cls._get_column_infos()
|
|
||||||
|
|
||||||
# add inherited fields that are not redefined locally
|
# add inherited fields that are not redefined locally
|
||||||
for name, field in fields.iteritems():
|
for name, field in fields.iteritems():
|
||||||
if name not in cls._fields:
|
if name not in cls._fields:
|
||||||
cls._add_field(name, field)
|
cls._add_field(name, field)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _inherits_reload(cls):
|
||||||
|
""" Recompute the _inherit_fields and _all_columns mappings. """
|
||||||
|
cls._inherit_fields = struct = {}
|
||||||
|
for parent_model, parent_field in cls._inherits.iteritems():
|
||||||
|
parent = cls.pool[parent_model]
|
||||||
|
for name, column in parent._columns.iteritems():
|
||||||
|
struct[name] = (parent_model, parent_field, column, parent_model)
|
||||||
|
for name, source in parent._inherit_fields.iteritems():
|
||||||
|
struct[name] = (parent_model, parent_field, source[2], source[3])
|
||||||
|
|
||||||
|
# old-api stuff
|
||||||
|
cls._all_columns = cls._get_column_infos()
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def _get_column_infos(cls):
|
def _get_column_infos(cls):
|
||||||
"""Returns a dict mapping all fields names (direct fields and
|
"""Returns a dict mapping all fields names (direct fields and
|
||||||
|
@ -2918,14 +2910,16 @@ class BaseModel(object):
|
||||||
@classmethod
|
@classmethod
|
||||||
def _inherits_check(cls):
|
def _inherits_check(cls):
|
||||||
for table, field_name in cls._inherits.items():
|
for table, field_name in cls._inherits.items():
|
||||||
if field_name not in cls._columns:
|
field = cls._fields.get(field_name)
|
||||||
|
if not field:
|
||||||
_logger.info('Missing many2one field definition for _inherits reference "%s" in "%s", using default one.', field_name, cls._name)
|
_logger.info('Missing many2one field definition for _inherits reference "%s" in "%s", using default one.', field_name, cls._name)
|
||||||
cls._columns[field_name] = fields.many2one(table, string="Automatically created field to link to parent %s" % table,
|
from .fields import Many2one
|
||||||
required=True, ondelete="cascade")
|
field = Many2one(table, string="Automatically created field to link to parent %s" % table, required=True, ondelete="cascade")
|
||||||
elif not cls._columns[field_name].required or cls._columns[field_name].ondelete.lower() not in ("cascade", "restrict"):
|
cls._add_field(field_name, field)
|
||||||
|
elif not field.required or field.ondelete.lower() not in ("cascade", "restrict"):
|
||||||
_logger.warning('Field definition for _inherits reference "%s" in "%s" must be marked as "required" with ondelete="cascade" or "restrict", forcing it to required + cascade.', field_name, cls._name)
|
_logger.warning('Field definition for _inherits reference "%s" in "%s" must be marked as "required" with ondelete="cascade" or "restrict", forcing it to required + cascade.', field_name, cls._name)
|
||||||
cls._columns[field_name].required = True
|
field.required = True
|
||||||
cls._columns[field_name].ondelete = "cascade"
|
field.ondelete = "cascade"
|
||||||
|
|
||||||
# reflect fields with delegate=True in dictionary cls._inherits
|
# reflect fields with delegate=True in dictionary cls._inherits
|
||||||
for field in cls._fields.itervalues():
|
for field in cls._fields.itervalues():
|
||||||
|
@ -2967,17 +2961,17 @@ class BaseModel(object):
|
||||||
|
|
||||||
# retrieve inherited fields
|
# retrieve inherited fields
|
||||||
cls._inherits_check()
|
cls._inherits_check()
|
||||||
cls._inherits_reload()
|
cls._init_inherited_fields()
|
||||||
|
|
||||||
# set up fields
|
# set up fields, and update their corresponding columns
|
||||||
for field in cls._fields.itervalues():
|
|
||||||
field.setup(self.env)
|
|
||||||
|
|
||||||
# update columns (fields may have changed)
|
|
||||||
for name, field in cls._fields.iteritems():
|
for name, field in cls._fields.iteritems():
|
||||||
if field.column:
|
field.setup(self.env)
|
||||||
|
if field.store or field.column:
|
||||||
cls._columns[name] = field.to_column()
|
cls._columns[name] = field.to_column()
|
||||||
|
|
||||||
|
# determine old-api cls._inherit_fields and cls._all_columns
|
||||||
|
cls._inherits_reload()
|
||||||
|
|
||||||
# group fields by compute to determine field.computed_fields
|
# group fields by compute to determine field.computed_fields
|
||||||
fields_by_compute = defaultdict(list)
|
fields_by_compute = defaultdict(list)
|
||||||
for field in cls._fields.itervalues():
|
for field in cls._fields.itervalues():
|
||||||
|
|
Loading…
Reference in New Issue