...
AttributeError: 'name'
+Unless you set a default value::
+
+ >>> class Person(Base):
+ >>> __tablename__ = 'person'
+ >>>
+ >>> id = Column(Integer, primary_key=True)
+ >>> data = Column(JSON)
+ >>>
+ >>> name = index_property('data', 'name', default=None) # See default
+
+ >>> person = Person()
+ >>> print(person.name)
+ None
+
+
The attributes are also accessible at the class level.
Below, we illustrate ``Person.name`` used to generate
an indexed SQL criteria::
"""
+ _NO_DEFAULT_ARGUMENT = object()
+
def __init__(
- self, attr_name, index, datatype=None,
- mutable=True, onebased=True):
+ self, attr_name, index, default=_NO_DEFAULT_ARGUMENT,
+ datatype=None, mutable=True, onebased=True):
"""Create a new :class:`.index_property`.
:param attr_name:
:param index:
The index to be used for getting and setting this value. This
should be the Python-side index value for integers.
+ :param default:
+ A value which will be returned instead of `AttributeError`
+ when there is not a value at given index.
:param datatype: default datatype to use when the field is empty.
By default, this is derived from the type of index used; a
Python list for an integer index, or a Python dictionary for
)
self.attr_name = attr_name
self.index = index
+ self.default = default
is_numeric = isinstance(index, int)
onebased = is_numeric and onebased
self.datatype = dict
self.onebased = onebased
+ def _fget_default(self):
+ if self.default == self._NO_DEFAULT_ARGUMENT:
+ raise AttributeError(self.attr_name)
+ else:
+ return self.default
+
def fget(self, instance):
attr_name = self.attr_name
column_value = getattr(instance, attr_name)
if column_value is None:
- raise AttributeError(self.attr_name)
+ return self._fget_default()
try:
value = column_value[self.index]
except (KeyError, IndexError):
- raise AttributeError(self.attr_name)
+ return self._fget_default()
else:
return value
j.field = 10
eq_(j.field, 10)
+ def test_get_default_value(self):
+ Base = declarative_base()
+
+ class J(Base):
+ __tablename__ = 'j'
+ id = Column(Integer, primary_key=True)
+ json = Column(JSON, default={})
+ default = index_property('json', 'field', default='default')
+ none = index_property('json', 'field', default=None)
+
+ j = J()
+ assert j.json is None
+
+ assert j.default == 'default'
+ assert j.none is None
+ j.json = {}
+ assert j.default == 'default'
+ assert j.none is None
+ j.default = None
+ assert j.default is None
+ assert j.none is None
+ j.none = 10
+ assert j.default is 10
+ assert j.none == 10
+
class IndexPropertyArrayTest(fixtures.DeclarativeMappedTest):