inside the EXISTS is aliased on the "remote" side to
distinguish it from the parent table.
+ - repaired behavior of == and != operators at the relation()
+ level when compared against NULL for one-to-one
+ relations [ticket:985]
+
- fixed bug whereby session.expire() attributes were not
loading on an polymorphically-mapped instance mapped
by a select_table mapper.
def __eq__(self, other):
if other is None:
- if self.prop.uselist:
+ if self.prop.direction == sync.ONETOMANY:
return ~sql.exists([1], self.prop.primaryjoin)
else:
return self.prop._optimized_compare(None)
return clause
def __ne__(self, other):
+ if other is None:
+ if self.prop.direction == sync.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 exceptions.InvalidRequestError("Can only compare a collection to an iterable object")
'addresses':relation(Address, backref='user'),
'orders':relation(Order, backref='user'), # o2m, m2o
})
- mapper(Address, addresses)
+ mapper(Address, addresses, properties={
+ 'dingaling':relation(Dingaling, uselist=False, backref="address") #o2o
+ })
+ mapper(Dingaling, dingalings)
mapper(Order, orders, properties={
'items':relation(Item, secondary=order_items, order_by=items.c.id), #m2m
'address':relation(Address), # m2o
assert [Order(id=5)] == sess.query(Order).filter(Order.address == None).all()
+ # o2o
+ dingaling = sess.query(Dingaling).get(2)
+ assert [Address(id=5)] == sess.query(Address).filter(Address.dingaling==dingaling).all()
+
def test_filter_by(self):
sess = create_session()
user = sess.query(User).get(8)
# one to many generates WHERE NOT EXISTS
assert [User(name='chuck')] == sess.query(User).filter_by(addresses = None).all()
-
+
+ def test_none_comparison(self):
+ sess = create_session()
+
+ # o2o
+ self.assertEquals([Address(id=1), Address(id=3), Address(id=4)], sess.query(Address).filter(Address.dingaling==None).all())
+ self.assertEquals([Address(id=2), Address(id=5)], sess.query(Address).filter(Address.dingaling != None).all())
+
+ # m2o
+ self.assertEquals([Order(id=5)], sess.query(Order).filter(Order.address==None).all())
+ self.assertEquals([Order(id=1), Order(id=2), Order(id=3), Order(id=4)], sess.query(Order).filter(Order.address!=None).all())
+
+ # o2m
+ self.assertEquals([User(id=10)], sess.query(User).filter(User.addresses==None).all())
+ self.assertEquals([User(id=7),User(id=8),User(id=9)], sess.query(User).filter(User.addresses!=None).all())
+
class AggregateTest(QueryTest):
def test_sum(self):
sess = create_session()