Skip to content

Commit

Permalink
Improve the Base database entity
Browse files Browse the repository at this point in the history
  • Loading branch information
lw committed Jan 2, 2014
1 parent 3ce235b commit bd39c17
Showing 1 changed file with 67 additions and 3 deletions.
70 changes: 67 additions & 3 deletions cms/db/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
# Copyright © 2010-2013 Giovanni Mascellani <[email protected]>
# Copyright © 2010-2012 Stefano Maggiolo <[email protected]>
# Copyright © 2010-2012 Matteo Boscariol <[email protected]>
# Copyright © 2013 Luca Wehrstedt <[email protected]>
# Copyright © 2013-2014 Luca Wehrstedt <[email protected]>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
Expand Down Expand Up @@ -197,6 +197,7 @@ def __init__(self, *args, **kwargs):
raise TypeError(
"%s.__init__() got None for keyword argument '%s',"
" which is not nullable" % (cls.__name__, prp.key))
setattr(self, prp.key, val)
else:
# TODO col_type.python_type contains the type that
# SQLAlchemy thinks is more appropriate. We could
Expand All @@ -223,8 +224,8 @@ def __init__(self, *args, **kwargs):
# Check if there were unknown arguments
if kwargs:
raise TypeError(
"%s.__init__() got an unexpected keyword argument '%s'\n%s" %
(cls.__name__, kwargs, kwargs.popitem()[0]))
"%s.__init__() got an unexpected keyword argument '%s'" %
(cls.__name__, kwargs.popitem()[0]))

@classmethod
def get_from_id(cls, id_, session):
Expand Down Expand Up @@ -267,6 +268,69 @@ def clone(self):
args = list(getattr(self, prp.key) for prp in self._col_props)
return cls(*args)

def get_attrs(self):
"""Return self.__dict__.
Limited to SQLAlchemy column properties.
return ({string: object}): the properties of this object.
"""
attrs = dict()
for prp in self._col_props:
if hasattr(self, prp.key):
attrs[prp.key] = getattr(self, prp.key)
return attrs

def set_attrs(self, attrs):
"""Do self.__dict__.update(attrs) with validation.
Limited to SQLAlchemy column and relationship properties.
attrs ({string: object}): the new properties we want to set on
this object.
"""
# We want to pop items without altering the caller's object.
attrs = attrs.copy()

for prp in self._col_props:
col = prp.columns[0]
col_type = type(col.type)

if prp.key in attrs:
val = attrs.pop(prp.key)

if val is None:
if not col.nullable:
raise TypeError(
"set_attrs() got None for keyword argument '%s',"
" which is not nullable" % prp.key)
setattr(self, prp.key, val)
else:
# TODO col_type.python_type contains the type that
# SQLAlchemy thinks is more appropriate. We could
# use that and drop _TYPE_MAP...
if not isinstance(val, _TYPE_MAP[col_type]):
raise TypeError(
"set_attrs() got a '%s' for keyword argument "
"'%s', which requires a '%s'" %
(type(val), prp.key, _TYPE_MAP[col_type]))
setattr(self, prp.key, val)

for prp in self._rel_props:
if prp.key in attrs:
val = attrs.pop(prp.key)

# TODO Some type validation (take a look at prp.uselist)
setattr(self, prp.key, val)

# Check if there were unknown arguments
if attrs:
raise TypeError(
"set_attrs() got an unexpected keyword argument '%s'" %
attrs.popitem()[0])


Base = declarative_base(engine, cls=Base, constructor=None)

Expand Down

0 comments on commit bd39c17

Please sign in to comment.