From 50dfbc7e793f1bcfdd22f9cffcefde31f14b186b Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Fri, 2 Jan 2009 18:22:50 +0000 Subject: - 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. --- lib/sqlalchemy/orm/attributes.py | 27 ++++++++++++++++++++++++--- lib/sqlalchemy/orm/properties.py | 2 ++ 2 files changed, 26 insertions(+), 3 deletions(-) (limited to 'lib') 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): -- cgit v1.2.1