diff options
| author | Mike Bayer <mike_mp@zzzcomputing.com> | 2009-01-02 18:22:50 +0000 |
|---|---|---|
| committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2009-01-02 18:22:50 +0000 |
| commit | 50dfbc7e793f1bcfdd22f9cffcefde31f14b186b (patch) | |
| tree | 000b7150983c40ec134a31b0d7b3addc0c679b30 /lib | |
| parent | a52a0c43c3d4880df53c46d1fd92fcf8d1a3a758 (diff) | |
| download | sqlalchemy-50dfbc7e793f1bcfdd22f9cffcefde31f14b186b.tar.gz | |
- Custom comparator classes used in conjunction with
column_property(), relation() etc. can define
new comparison methods on the Comparator, which will
become available via __getattr__() on the
InstrumentedAttribute. In the case of synonym()
or comparable_property(), attributes are resolved first
on the user-defined descriptor, then on the user-defined
comparator.
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/sqlalchemy/orm/attributes.py | 27 | ||||
| -rw-r--r-- | lib/sqlalchemy/orm/properties.py | 2 |
2 files changed, 26 insertions, 3 deletions
diff --git a/lib/sqlalchemy/orm/attributes.py b/lib/sqlalchemy/orm/attributes.py index df607adf8..2b2760208 100644 --- a/lib/sqlalchemy/orm/attributes.py +++ b/lib/sqlalchemy/orm/attributes.py @@ -131,7 +131,17 @@ class QueryableAttribute(interfaces.PropComparator): def hasparent(self, state, optimistic=False): return self.impl.hasparent(state, optimistic=optimistic) - + + def __getattr__(self, key): + try: + return getattr(self.comparator, key) + except AttributeError: + raise AttributeError('Neither %r object nor %r object has an attribute %r' % ( + type(self).__name__, + type(self.comparator).__name__, + key) + ) + def __str__(self): return repr(self.parententity) + "." + self.property.key @@ -195,8 +205,19 @@ def proxied_attribute_factory(descriptor): return descriptor.__delete__(instance) def __getattr__(self, attribute): - """Delegate __getattr__ to the original descriptor.""" - return getattr(descriptor, attribute) + """Delegate __getattr__ to the original descriptor and/or comparator.""" + + try: + return getattr(descriptor, attribute) + except AttributeError: + try: + return getattr(self._comparator, attribute) + except AttributeError: + raise AttributeError('Neither %r object nor %r object has an attribute %r' % ( + type(descriptor).__name__, + type(self._comparator).__name__, + attribute) + ) def _property(self): return self._parententity.get_property(self.key, resolve_synonyms=True) diff --git a/lib/sqlalchemy/orm/properties.py b/lib/sqlalchemy/orm/properties.py index bf9bda366..675b505e7 100644 --- a/lib/sqlalchemy/orm/properties.py +++ b/lib/sqlalchemy/orm/properties.py @@ -42,6 +42,7 @@ class ColumnProperty(StrategizedProperty): self.group = kwargs.pop('group', None) self.deferred = kwargs.pop('deferred', False) self.comparator_factory = kwargs.pop('comparator_factory', self.__class__.Comparator) + self.descriptor = kwargs.pop('descriptor', None) self.extension = kwargs.pop('extension', None) util.set_creation_order(self) if self.deferred: @@ -206,6 +207,7 @@ class SynonymProperty(MapperProperty): if obj is None: return s return getattr(obj, self.name) + self.descriptor = SynonymProp() def comparator_callable(prop, mapper): |
