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.

Reply via email to