summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/orm
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2008-10-18 17:34:52 +0000
committerMike Bayer <mike_mp@zzzcomputing.com>2008-10-18 17:34:52 +0000
commit1127b10b278440247f18d1859e1f70a4aafaa9fb (patch)
treed1b149d4bf92b1a01235000490438bfd91391a0e /lib/sqlalchemy/orm
parent654794cdcf89eb7842ddf06bd9316bd860bca9e7 (diff)
downloadsqlalchemy-1127b10b278440247f18d1859e1f70a4aafaa9fb.tar.gz
- "not equals" comparisons of simple many-to-one relation
to an instance will not drop into an EXISTS clause and will compare foreign key columns instead. - removed not-really-working use cases of comparing a collection to an iterable. Use contains() to test for collection membership. - Further simplified SELECT compilation and its relationship to result row processing. - Direct execution of a union() construct will properly set up result-row processing. [ticket:1194]
Diffstat (limited to 'lib/sqlalchemy/orm')
-rw-r--r--lib/sqlalchemy/orm/properties.py40
1 files changed, 17 insertions, 23 deletions
diff --git a/lib/sqlalchemy/orm/properties.py b/lib/sqlalchemy/orm/properties.py
index d2f5dae0c..40bca8a11 100644
--- a/lib/sqlalchemy/orm/properties.py
+++ b/lib/sqlalchemy/orm/properties.py
@@ -347,18 +347,7 @@ class PropertyLoader(StrategizedProperty):
else:
return self.prop._optimized_compare(None)
elif self.prop.uselist:
- if not hasattr(other, '__iter__'):
- raise sa_exc.InvalidRequestError("Can only compare a collection to an iterable object. Use contains().")
- else:
- j = self.prop.primaryjoin
- if self.prop.secondaryjoin:
- j = j & self.prop.secondaryjoin
- clauses = []
- for o in other:
- clauses.append(
- sql.exists([1], j & sql.and_(*[x==y for (x, y) in zip(self.prop.mapper.primary_key, self.prop.mapper.primary_key_from_instance(o))]))
- )
- return sql.and_(*clauses)
+ raise sa_exc.InvalidRequestError("Can't compare a collection to an object or collection; use contains() to test for membership.")
else:
return self.prop._optimized_compare(other)
@@ -418,25 +407,30 @@ class PropertyLoader(StrategizedProperty):
return clause
def __negated_contains_or_equals(self, other):
+ if self.prop.direction == MANYTOONE:
+ state = attributes.instance_state(other)
+ strategy = self.prop._get_strategy(strategies.LazyLoader)
+ if strategy.use_get:
+ return sql.and_(*[
+ sql.or_(
+ x !=
+ self.prop.mapper._get_committed_state_attr_by_column(state, y),
+ x == None)
+ for (x, y) in self.prop.local_remote_pairs])
+
criterion = sql.and_(*[x==y for (x, y) in zip(self.prop.mapper.primary_key, self.prop.mapper.primary_key_from_instance(other))])
return ~self._criterion_exists(criterion)
def __ne__(self, other):
- # TODO: simplify MANYTOONE comparsion when
- # the 'use_get' flag is enabled
-
if other is None:
if self.prop.direction == MANYTOONE:
return sql.or_(*[x!=None for x in self.prop._foreign_keys])
- elif self.prop.uselist:
- return self.any()
else:
- return self.has()
-
- if self.prop.uselist and not hasattr(other, '__iter__'):
- raise sa_exc.InvalidRequestError("Can only compare a collection to an iterable object")
-
- return self.__negated_contains_or_equals(other)
+ return self._criterion_exists()
+ elif self.prop.uselist:
+ raise sa_exc.InvalidRequestError("Can't compare a collection to an object or collection; use contains() to test for membership.")
+ else:
+ return self.__negated_contains_or_equals(other)
def compare(self, op, value, value_is_parent=False):
if op == operators.eq: