Commits

Mike Bayer committed c1647ad

- fixed Query bug when filter_by() compares a relation against None
[ticket:899]

  • Participants
  • Parent commits d99ca96

Comments (0)

Files changed (3)

      
    - 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

File lib/sqlalchemy/orm/properties.py

     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:

File test/orm/query.py

 
         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()
         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)