thanks for this test. this is issue
https://bitbucket.org/zzzeek/sqlalchemy/issues/3788/simple-many-to-one-comparison-is-sensitive
and the fix is going through targeted at 1.1 for now.
On 09/02/2016 12:39 AM, YKdvd wrote:
I think I may have found the issue. If I modify your example so that
"C.k1" is a declared_attr, the assertion on the second C instance loads
the (100,1000) record from table "ab" again. I originally had my "k1"
in a mixin, but it looks like the mixin isn't involved, and it is purely
the declared_attr. I assume that the "k1" coming from the declared_attr
doesn't have quite the right karma in some way when used in the
ForeignKeyConstraint in C that makes the relationship to AB? I'll have
to go back and dig into the docs, but am I using declared_attr decorator
improperly, or is there a better way to refer to "k1" in the
ForeignKeyConstraint?
My modified version of your test is below. Change the "useDeclared"
variable to False to bypass the declared_attr behaviour and recover the
working of the original test.
|
from sqlalchemy import *
from sqlalchemy.orm import *
from sqlalchemy.ext.declarative import declarative_base, declared_attr
useDeclared = True# set True to see unneeded select on #2
useMixin = False# put the declared in the mixin if True
Base = declarative_base()
class A(Base):
__tablename__ = 'a'
id = Column(Integer, primary_key=True)
assoc = relationship("AB")
class B(Base):
__tablename__ = 'b'
id = Column(Integer, primary_key=True)
class AB(Base):
__tablename__ = 'ab'
a_id = Column(ForeignKey('a.id'), primary_key=True)
b_id = Column(ForeignKey('b.id'), primary_key=True)
a = relationship("A")
b = relationship("B")
class Mixin_C(object):
if useMixin:
@declared_attr
def k1(cls):
print "DECLARED K1"
return Column(Integer)
class C(Base, Mixin_C):
__tablename__ = 'c'
id = Column(Integer, primary_key=True)
if not useMixin:
if useDeclared:
@declared_attr
def k1(cls):
print "declared without mixin"
return Column(Integer)
else:
print "INLINE k1"
k1 = Column(Integer)
k2 = Column(Integer)
assoc = relationship("AB")
__table_args__ = (
ForeignKeyConstraint(['k1', 'k2'], ['ab.a_id', 'ab.b_id']), {})
e = create_engine("sqlite://", echo=True)
Base.metadata.create_all(e)
s = Session(e)
a, b = A(id=100), B(id=1000)
ab = AB(a=a, b=b)
c1 = C(id=1, assoc=ab)
c2 = C(id=2, assoc=ab)
s.add_all([a, b, ab, c1, c2])
s.commit()
s.close() # clears everything
c1 = s.query(C).get(1)
print "#1 EMITS LAZYLOAD:"
assoc = c1.assoc # note we keep a strong reference here
c2 = s.query(C).get(2)
print "\n#2 SHOULD NOT EMIT LAZYLOAD%s"%("" if not useDeclared else ",
but will because of declared_attr")
assert c2.assoc is assoc
|
--
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 sqlalchemy+unsubscr...@googlegroups.com
<mailto:sqlalchemy+unsubscr...@googlegroups.com>.
To post to this group, send email to sqlalchemy@googlegroups.com
<mailto:sqlalchemy@googlegroups.com>.
Visit this group at https://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.
--
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 sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at https://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.