summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/sqlalchemy/ext/hybrid.py31
-rw-r--r--lib/sqlalchemy/orm/attributes.py53
-rw-r--r--lib/sqlalchemy/orm/mapper.py4
-rw-r--r--lib/sqlalchemy/orm/properties.py17
-rw-r--r--lib/sqlalchemy/orm/query.py3
-rw-r--r--test/orm/test_mapper.py2
6 files changed, 51 insertions, 59 deletions
diff --git a/lib/sqlalchemy/ext/hybrid.py b/lib/sqlalchemy/ext/hybrid.py
index 3134db12d..b74b407c5 100644
--- a/lib/sqlalchemy/ext/hybrid.py
+++ b/lib/sqlalchemy/ext/hybrid.py
@@ -63,6 +63,7 @@ or as the class itself::
"""
from sqlalchemy import util
+from sqlalchemy.orm import attributes, interfaces
class method(object):
def __init__(self, func, expr=None):
@@ -111,4 +112,34 @@ class property_(object):
self.expr = expr
return self
+ def compare_with(self, comparator):
+ proxy_attr = attributes.\
+ create_proxied_attribute(self)
+ def expr(owner):
+ return proxy_attr(self.__name__, self, comparator(owner))
+ self.expr = expr
+ return self
+
+
+class Comparator(interfaces.PropComparator):
+ def __init__(self, expression, adapter=None):
+ self._expression = expression
+ self.adapter = adapter
+
+ @property
+ def expression(self):
+ return self.__clause_element__()
+
+ def __clause_element__(self):
+ if self.adapter:
+ return self.adapter(self._expression)
+ else:
+ return self._expression
+
+ def adapted(self, adapter):
+ return self.__class__(self._expression, adapter)
+
+
+
+ \ No newline at end of file
diff --git a/lib/sqlalchemy/orm/attributes.py b/lib/sqlalchemy/orm/attributes.py
index c21585cea..ea04b0910 100644
--- a/lib/sqlalchemy/orm/attributes.py
+++ b/lib/sqlalchemy/orm/attributes.py
@@ -162,17 +162,10 @@ class InstrumentedAttribute(QueryableAttribute):
return self.impl.get(instance_state(instance),
instance_dict(instance))
-class _ProxyImpl(object):
- accepts_scalar_loader = False
- expire_missing = True
-
- def __init__(self, key):
- self.key = key
-
-def proxied_attribute_factory(descriptor):
- """Create an InstrumentedAttribute / user descriptor hybrid.
+def create_proxied_attribute(descriptor):
+ """Create an QueryableAttribute / user descriptor hybrid.
- Returns a new InstrumentedAttribute type that delegates descriptor
+ Returns a new QueryableAttribute type that delegates descriptor
behavior and getattr() to the given descriptor.
"""
@@ -181,10 +174,8 @@ def proxied_attribute_factory(descriptor):
def __init__(self, key, descriptor, comparator, adapter=None):
self.key = key
- # maintain ProxiedAttribute.user_prop compatability.
- self.descriptor = self.user_prop = descriptor
+ self.descriptor = descriptor
self._comparator = comparator
- self.impl = _ProxyImpl(key)
self.adapter = adapter
@util.memoized_property
@@ -199,22 +190,10 @@ def proxied_attribute_factory(descriptor):
return self.__class__(self.key, self.descriptor,
self._comparator,
adapter)
-
- def __get__(self, instance, owner):
- """Delegate __get__ to the original descriptor."""
- if instance is None:
- descriptor.__get__(instance, owner)
- return self
- return descriptor.__get__(instance, owner)
-
- def __set__(self, instance, value):
- """Delegate __set__ to the original descriptor."""
- return descriptor.__set__(instance, value)
-
- def __delete__(self, instance):
- """Delegate __delete__ to the original descriptor."""
- return descriptor.__delete__(instance)
+ def __str__(self):
+ return self.key
+
def __getattr__(self, attribute):
"""Delegate __getattr__ to the original descriptor and/or
comparator."""
@@ -223,7 +202,7 @@ def proxied_attribute_factory(descriptor):
return getattr(descriptor, attribute)
except AttributeError:
try:
- return getattr(self.comparator, attribute)
+ return getattr(self._comparator, attribute)
except AttributeError:
raise AttributeError(
'Neither %r object nor %r object has an attribute %r' % (
@@ -1424,15 +1403,12 @@ def unregister_class(class_):
instrumentation_registry.unregister(class_)
def register_attribute(class_, key, **kw):
- proxy_property = kw.pop('proxy_property', None)
-
comparator = kw.pop('comparator', None)
parententity = kw.pop('parententity', None)
doc = kw.pop('doc', None)
- register_descriptor(class_, key, proxy_property,
+ register_descriptor(class_, key,
comparator, parententity, doc=doc)
- if not proxy_property:
- register_attribute_impl(class_, key, **kw)
+ register_attribute_impl(class_, key, **kw)
def register_attribute_impl(class_, key,
uselist=False, callable_=None,
@@ -1464,16 +1440,11 @@ def register_attribute_impl(class_, key,
manager.post_configure_attribute(key)
-def register_descriptor(class_, key, proxy_property=None, comparator=None,
+def register_descriptor(class_, key, comparator=None,
parententity=None, property_=None, doc=None):
manager = manager_of_class(class_)
- if proxy_property:
- raise NotImplementedError()
- proxy_type = proxied_attribute_factory(proxy_property)
- descriptor = proxy_type(key, proxy_property, comparator, parententity)
- else:
- descriptor = InstrumentedAttribute(key, comparator=comparator,
+ descriptor = InstrumentedAttribute(key, comparator=comparator,
parententity=parententity)
descriptor.__doc__ = doc
diff --git a/lib/sqlalchemy/orm/mapper.py b/lib/sqlalchemy/orm/mapper.py
index 4e7702698..1895798b1 100644
--- a/lib/sqlalchemy/orm/mapper.py
+++ b/lib/sqlalchemy/orm/mapper.py
@@ -1074,10 +1074,6 @@ class Mapper(object):
return result
def _is_userland_descriptor(self, obj):
-# return not isinstance(obj,
-# (MapperProperty, attributes.InstrumentedAttribute)) and \
-# hasattr(obj, '__get__')
-
return not isinstance(obj,
(MapperProperty, attributes.InstrumentedAttribute)) and \
hasattr(obj, '__get__') and not \
diff --git a/lib/sqlalchemy/orm/properties.py b/lib/sqlalchemy/orm/properties.py
index 50d95b777..d0de4bbbb 100644
--- a/lib/sqlalchemy/orm/properties.py
+++ b/lib/sqlalchemy/orm/properties.py
@@ -290,14 +290,15 @@ class DescriptorProperty(MapperProperty):
)
proxy_attr = attributes.\
- proxied_attribute_factory(self.descriptor
- or descriptor)\
- (self.key, self.descriptor or descriptor,
- lambda: self._comparator_factory(mapper))
+ create_proxied_attribute(self.descriptor or descriptor)\
+ (
+ self.key,
+ self.descriptor or descriptor,
+ lambda: self._comparator_factory(mapper)
+ )
def get_comparator(owner):
return proxy_attr
descriptor.expr = get_comparator
-
descriptor.impl = _ProxyImpl(self.key)
mapper.class_manager.instrument_attribute(self.key, descriptor)
@@ -328,8 +329,6 @@ class ConcreteInheritedProperty(DescriptorProperty):
"""
- extension = None
-
def _comparator_factory(self, mapper):
comparator_callable = None
@@ -361,8 +360,6 @@ class ConcreteInheritedProperty(DescriptorProperty):
class SynonymProperty(DescriptorProperty):
- extension = None
-
def __init__(self, name, map_column=None,
descriptor=None, comparator_factory=None,
doc=None):
@@ -436,8 +433,6 @@ class ComparableProperty(DescriptorProperty):
return self.comparator_factory(self, mapper)
-
-
class RelationshipProperty(StrategizedProperty):
"""Describes an object property that holds a single item or list
of items that correspond to a related database table.
diff --git a/lib/sqlalchemy/orm/query.py b/lib/sqlalchemy/orm/query.py
index c05dfe1e4..ed1eefee4 100644
--- a/lib/sqlalchemy/orm/query.py
+++ b/lib/sqlalchemy/orm/query.py
@@ -866,7 +866,8 @@ class Query(object):
clauses = [_entity_descriptor(self._joinpoint_zero(), key) == value
for key, value in kwargs.iteritems()]
-
+ import pdb
+ pdb.set_trace()
return self.filter(sql.and_(*clauses))
@_generative(_no_statement_condition, _no_limit_offset)
diff --git a/test/orm/test_mapper.py b/test/orm/test_mapper.py
index c9b86e8ee..194ba67a5 100644
--- a/test/orm/test_mapper.py
+++ b/test/orm/test_mapper.py
@@ -901,8 +901,6 @@ class MapperTest(_fixtures.FixtureTest):
args = (UCComparator,)
mapper(User, users, properties=dict(
uc_name = sa.orm.comparable_property(*args)))
-# import pdb
-# pdb.set_trace()
return User
for User in (map_(True), map_(False)):