Improve creation time of model instances by keeping a dictionary of default values

This commit is contained in:
Itai Shirav 2018-05-14 07:37:56 -04:00
parent ab0755ad90
commit 2bca8b4fb8
2 changed files with 11 additions and 9 deletions

View File

@ -12,6 +12,10 @@ Unreleased
- Added attribute `server_version` to Database class (M1hacka) - Added attribute `server_version` to Database class (M1hacka)
- Changed `Engine.create_table_sql()`, `Engine.drop_table_sql()`, `Model.create_table_sql()`, `Model.drop_table_sql()` parameter to db from db_name (M1hacka) - Changed `Engine.create_table_sql()`, `Engine.drop_table_sql()`, `Model.create_table_sql()`, `Model.drop_table_sql()` parameter to db from db_name (M1hacka)
- Fix parsing of datetime column type when it includes a timezone (M1hacka) - Fix parsing of datetime column type when it includes a timezone (M1hacka)
- Rename `Model.system` to `Model._system` to prevent collision with a column that has the same name
- Rename `Model.readonly` to `Model._readonly` to prevent collision with a column that has the same name
- The `field_names` argument to `Model.to_tsv` is now mandatory
- Improve creation time of model instances by keeping a dictionary of default values
v0.9.8 v0.9.8
------ ------

View File

@ -34,10 +34,14 @@ class ModelBase(type):
fields.update({n: f for n, f in iteritems(attrs) if isinstance(f, Field)}) fields.update({n: f for n, f in iteritems(attrs) if isinstance(f, Field)})
fields = sorted(iteritems(fields), key=lambda item: item[1].creation_counter) fields = sorted(iteritems(fields), key=lambda item: item[1].creation_counter)
# Build a dictionary of default values
defaults = {n: f.to_python(f.default, pytz.UTC) for n, f in fields}
attrs = dict( attrs = dict(
attrs, attrs,
_fields=OrderedDict(fields), _fields=OrderedDict(fields),
_writable_fields=OrderedDict([f for f in fields if not f[1].readonly]), _writable_fields=OrderedDict([f for f in fields if not f[1].readonly]),
_defaults=defaults
) )
return super(ModelBase, cls).__new__(cls, str(name), bases, attrs) return super(ModelBase, cls).__new__(cls, str(name), bases, attrs)
@ -116,9 +120,8 @@ class Model(with_metaclass(ModelBase)):
Unrecognized field names will cause an `AttributeError`. Unrecognized field names will cause an `AttributeError`.
''' '''
super(Model, self).__init__() super(Model, self).__init__()
# Assign default values
self._database = None self.__dict__.update(self._defaults)
# Assign field values from keyword arguments # Assign field values from keyword arguments
for name, value in iteritems(kwargs): for name, value in iteritems(kwargs):
field = self.get_field(name) field = self.get_field(name)
@ -126,10 +129,6 @@ class Model(with_metaclass(ModelBase)):
setattr(self, name, value) setattr(self, name, value)
else: else:
raise AttributeError('%s does not have a field called %s' % (self.__class__.__name__, name)) raise AttributeError('%s does not have a field called %s' % (self.__class__.__name__, name))
# Assign default values for fields not included in the keyword arguments
for name, field in iteritems(self.fields()):
if name not in kwargs:
setattr(self, name, field.default)
def __setattr__(self, name, value): def __setattr__(self, name, value):
''' '''
@ -168,8 +167,7 @@ class Model(with_metaclass(ModelBase)):
''' '''
Gets a `Field` instance given its name, or `None` if not found. Gets a `Field` instance given its name, or `None` if not found.
''' '''
field = getattr(self.__class__, name, None) return self._fields.get(name)
return field if isinstance(field, Field) else None
@classmethod @classmethod
def table_name(cls): def table_name(cls):