Awesome! The changes should be able to cover the issue. On Saturday, June 8, 2013 12:40:51 PM UTC-5, Michael Bayer wrote: > > > On Jun 8, 2013, at 1:33 AM, Greg Yang <[email protected] <javascript:>> > wrote: > > > if __name__ == '__main__': > > engine = create_engine('sqlite:///:memory:') > > Session = sessionmaker(engine) > > session = Session() > > Base.metadata.create_all(engine) > > > > b1 = B() > > b2 = B() > > b3 = B() > > > > b1.a_color = 'blue' > > session.add_all([b1, b2, b3]) > > > > q = session.query(B).filter(B.a_color == None).all() > > p = session.query(B).filter(B.a_color != None).all() > > > > assert q == [] > > assert set(p) == set([b1, b2, b3]) > > > > I find it surprising that, when only b1 really has a color string > through B.a_color, filtering for B.a_color == None doesn't return b2 and > b3, and filtering for B.a_color != None returns b2 and b3 at all. The > latter is especially unintuitive. > > The scalar comparison case was only rudimentally implemented. Along > these lines, the case of query(B).filter(B.a_color != 'blue') also needed > to be covered. Keeping in mind that in SQL, "x != 'somevalue'" does *not* > return rows where "x IS NULL", this will now return those B's for which an > A with non-NULL a_color is present but not equal to 'blue'. > > While the results are pretty wrong especially in the != None case, this > seems strongly like an 0.9 only change, as it is very possible that > applications are relying upon the current behavior. Particularly the "x > == None" case not returning records for which an association row is not > present could break an application that isn't prepared for those rows. The > "x != 'somevalue'" case behaves very differently as well, no longer > returning rows for which the association is missing. An illustration of > all these cases contrasted can be seen in > http://www.sqlalchemy.org/trac/ticket/2751. The changes are committed > in r20d1e9c3fa8ccc992079. > > > > > On a similar note, is there a way to get a_re.has() or equivalent > through only a_color? This can be important when a_re is supposed to be a > private variable, and only the string a_color is exposed. I originally > thought that != None would do the trick but that doesn't work, as I've > shown here. > > this is like a "special operation" so I also added support for an empty > call to B.a_color.has(). If you put criterion in there, it raises, because > while you can do that, it doesn't really make any sense. The difference > between B.a_color.has() and B.a_color != None is that the former will > return you rows for which an A exists, regardless of whether or not A.color > is NULL. > > >
-- You received this message because you are subscribed to the Google Groups "sqlalchemy" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To post to this group, send email to [email protected]. Visit this group at http://groups.google.com/group/sqlalchemy?hl=en. For more options, visit https://groups.google.com/groups/opt_out.
