]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- fixed Query bug when filter_by() compares a relation against None
authorMike Bayer <mike_mp@zzzcomputing.com>
Sat, 29 Dec 2007 18:50:46 +0000 (18:50 +0000)
committerMike Bayer <mike_mp@zzzcomputing.com>
Sat, 29 Dec 2007 18:50:46 +0000 (18:50 +0000)
[ticket:899]

CHANGES
lib/sqlalchemy/orm/properties.py
test/orm/query.py

diff --git a/CHANGES b/CHANGES
index 8f379be1a7cb78a311980af96ccfebe8d700d2dd..e8d066fb2ac92901cc8f49ebb454212bc96fbf8c 100644 (file)
--- 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
index e0bf2e6e813b9f01ca8f2323d73188d067665b2b..734b962a4fd4aec087650da3c2926d70ae253cee 100644 (file)
@@ -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:
index 9471f1012a2753b17fab6663ef5c9cad45973c96..4a5097afd5bcc300b0b2d19b9010acdd11f52708 100644 (file)
@@ -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)