summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/orm/properties.py
diff options
context:
space:
mode:
Diffstat (limited to 'lib/sqlalchemy/orm/properties.py')
-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: