]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- `expression.null()` is fully understood the same way
authorMike Bayer <mike_mp@zzzcomputing.com>
Mon, 12 Oct 2009 22:29:08 +0000 (22:29 +0000)
committerMike Bayer <mike_mp@zzzcomputing.com>
Mon, 12 Oct 2009 22:29:08 +0000 (22:29 +0000)
None is when comparing an object/collection-referencing
attribute within query.filter(), filter_by(), etc.
[ticket:1415]

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

diff --git a/CHANGES b/CHANGES
index f6d3ef5e6073aaabc41b4f8a7d3d3cdbbacdf3df..aec67f28c04238efbe9f5820444c7495a646f7f2 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -42,6 +42,11 @@ CHANGES
   - the "dont_load=True" flag on Session.merge() is deprecated
     and is now "load=False".
 
+  - `expression.null()` is fully understood the same way
+    None is when comparing an object/collection-referencing
+    attribute within query.filter(), filter_by(), etc.
+    [ticket:1415]
+    
   - many-to-one relations now fire off a lazyload in fewer
     cases, including in most cases will not fetch the "old"
     value when a new one is replaced.
index f49f5fe88a464ee7ffb9849633c6a62d34fe2a2a..b99ce093a562435a497b91ac5ed40c0ba78cb530 100644 (file)
@@ -23,6 +23,7 @@ from sqlalchemy.orm.interfaces import (
     MANYTOMANY, MANYTOONE, MapperProperty, ONETOMANY, PropComparator,
     StrategizedProperty,
     )
+from types import NoneType
 
 __all__ = ('ColumnProperty', 'CompositeProperty', 'SynonymProperty',
            'ComparableProperty', 'RelationProperty', 'BackRef')
@@ -471,7 +472,7 @@ class RelationProperty(StrategizedProperty):
         __hash__ = None
         
         def __eq__(self, other):
-            if other is None:
+            if isinstance(other, (NoneType, expression._Null)):
                 if self.property.direction in [ONETOMANY, MANYTOMANY]:
                     return ~self._criterion_exists()
                 else:
@@ -581,7 +582,7 @@ class RelationProperty(StrategizedProperty):
             return ~self._criterion_exists(criterion)
 
         def __ne__(self, other):
-            if other is None:
+            if isinstance(other, (NoneType, expression._Null)):
                 if self.property.direction == MANYTOONE:
                     return sql.or_(*[x!=None for x in self.property._foreign_keys])
                 else:
index 0ec2b998d98fb78ad5ff2b7e0400d7936659171f..a9319608dc97e74c772d62b7dc08f25e7cf52a8a 100644 (file)
@@ -737,6 +737,7 @@ class FilterTest(QueryTest):
 
         # generates an IS NULL
         assert [] == sess.query(Address).filter(Address.user == None).all()
+        assert [] == sess.query(Address).filter(Address.user == null()).all()
 
         assert [Order(id=5)] == sess.query(Order).filter(Order.address == None).all()
 
@@ -755,17 +756,32 @@ class FilterTest(QueryTest):
 
         # many to one generates IS NULL
         assert [] == sess.query(Address).filter_by(user = None).all()
+        assert [] == sess.query(Address).filter_by(user = null()).all()
 
         # one to many generates WHERE NOT EXISTS
         assert [User(name='chuck')] == sess.query(User).filter_by(addresses = None).all()
+        assert [User(name='chuck')] == sess.query(User).filter_by(addresses = null()).all()
     
     def test_none_comparison(self):
         sess = create_session()
         
+        # scalar
+        eq_(
+            [Order(description="order 5")],
+            sess.query(Order).filter(Order.address_id==None).all()
+        )
+        eq_(
+            [Order(description="order 5")],
+            sess.query(Order).filter(Order.address_id==null()).all()
+        )
+        
         # o2o
         eq_([Address(id=1), Address(id=3), Address(id=4)], 
             sess.query(Address).filter(Address.dingaling==None).order_by(Address.id).all())
+        eq_([Address(id=1), Address(id=3), Address(id=4)], 
+            sess.query(Address).filter(Address.dingaling==null()).order_by(Address.id).all())
         eq_([Address(id=2), Address(id=5)], sess.query(Address).filter(Address.dingaling != None).order_by(Address.id).all())
+        eq_([Address(id=2), Address(id=5)], sess.query(Address).filter(Address.dingaling != null()).order_by(Address.id).all())
         
         # m2o
         eq_([Order(id=5)], sess.query(Order).filter(Order.address==None).all())