- changed status to resolved
relationship comparisons to None are also leaking NEVER_SET, but also are potentially not forwards-compatible
Issue #3371
resolved
from sqlalchemy import *
from sqlalchemy.orm import *
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
class A(Base):
__tablename__ = 'a'
id = Column(Integer, primary_key=True)
status = Column(Integer)
class B(Base):
__tablename__ = 'b'
id = Column(Integer, primary_key=True)
a_id = Column(ForeignKey('a.id'))
status = Column(Integer)
a = relationship("A")
special_a = relationship(
"A",
primaryjoin="and_(A.id == B.a_id, A.status == B.status)"
)
e = create_engine("sqlite://", echo=True)
Base.metadata.create_all(e)
s = Session(e)
print s.query(B).filter(B.special_a == A()).all()
in SA 1.0 we get the NEVER_SET symbols:
#!
SELECT b.id AS b_id, b.a_id AS b_a_id, b.status AS b_status
FROM b
WHERE ? = b.a_id AND ? = b.status
2015-04-20 15:04:06,533 INFO sqlalchemy.engine.base.Engine (symbol('NEVER_SET'), symbol('NEVER_SET'))
however, in 0.9 we still get a query that isn't forwards compatible, if we learn to fix those = comparisons to be "IS" for a NULL value:
#!
SELECT b.id AS b_id, b.a_id AS b_a_id, b.status AS b_status
FROM b
WHERE ? = b.a_id AND ? = b.status
2015-04-20 15:04:48,556 INFO sqlalchemy.engine.base.Engine (None, None)
above, if we ever fixed "? = b.status" to be "b.status IS NULL", the results would change.
therefore we should emit a warning, at least when the comparison is against a column that is not primary_key=True (for PK=true, which is the common case, PK cols are never NULL so the "False" comparison is OK).
Comments (1)
-
reporter - Log in to comment
#3371, and also made negated_contains_or_equals() use state_attr_by_column() just like a non-negated comparison, fixes#3374→ <<cset a3af638e1a95>>