From: Mike Bayer Date: Sat, 29 Dec 2007 18:50:46 +0000 (+0000) Subject: - fixed Query bug when filter_by() compares a relation against None X-Git-Tag: rel_0_4_2~11 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=90d38c7407e532462059d2e98cb8d3bab31f7a36;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git - fixed Query bug when filter_by() compares a relation against None [ticket:899] --- diff --git a/CHANGES b/CHANGES index 8f379be1a7..e8d066fb2a 100644 --- a/CHANGES +++ b/CHANGES @@ -107,6 +107,9 @@ CHANGES - columns which are missing from a Query's select statement now get automatically deferred during load. + + - fixed Query bug when filter_by() compares a relation against None + [ticket:899] - improved support for pickling of mapped entities. Per-instance lazy/deferred/expired callables are now serializable so that diff --git a/lib/sqlalchemy/orm/properties.py b/lib/sqlalchemy/orm/properties.py index e0bf2e6e81..734b962a4f 100644 --- a/lib/sqlalchemy/orm/properties.py +++ b/lib/sqlalchemy/orm/properties.py @@ -309,7 +309,10 @@ class PropertyLoader(StrategizedProperty): def compare(self, op, value, value_is_parent=False): if op == operators.eq: if value is None: - return ~sql.exists([1], self.prop.mapper.mapped_table, self.prop.primaryjoin) + if self.uselist: + return ~sql.exists([1], self.primaryjoin) + else: + return self._optimized_compare(None, value_is_parent=value_is_parent) else: return self._optimized_compare(value, value_is_parent=value_is_parent) else: diff --git a/test/orm/query.py b/test/orm/query.py index 9471f1012a..4a5097afd5 100644 --- a/test/orm/query.py +++ b/test/orm/query.py @@ -381,6 +381,17 @@ class FilterTest(QueryTest): assert [Order(id=5)] == sess.query(Order).filter(Order.address == None).all() + def test_filter_by(self): + sess = create_session() + user = sess.query(User).get(8) + assert [Address(id=2), Address(id=3), Address(id=4)] == sess.query(Address).filter_by(user=user).all() + + # many to one generates IS NULL + assert [] == sess.query(Address).filter_by(user = None).all() + + # one to many generates WHERE NOT EXISTS + assert [User(name='chuck')] == sess.query(User).filter_by(addresses = None).all() + class AggregateTest(QueryTest): def test_sum(self): sess = create_session() @@ -471,6 +482,10 @@ class ParentTest(QueryTest): o = sess.query(Order).with_parent(u1).filter(orders.c.id>2).all() assert [Order(description="order 3"), Order(description="order 5")] == o + # test against None for parent? this can't be done with the current API since we don't know + # what mapper to use + #assert sess.query(Order).with_parent(None, property='addresses').all() == [Order(description="order 5")] + def test_noparent(self): sess = create_session() q = sess.query(User)