summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2009-01-02 18:22:50 +0000
committerMike Bayer <mike_mp@zzzcomputing.com>2009-01-02 18:22:50 +0000
commit50dfbc7e793f1bcfdd22f9cffcefde31f14b186b (patch)
tree000b7150983c40ec134a31b0d7b3addc0c679b30 /lib
parenta52a0c43c3d4880df53c46d1fd92fcf8d1a3a758 (diff)
downloadsqlalchemy-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.py27
-rw-r--r--lib/sqlalchemy/orm/properties.py2
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):