On Jul 13, 2013, at 11:37 AM, Paul Johnston <paul....@gmail.com> wrote:

> Hi,
> 
> I've just been debugging a slow running query:
> 
> products = 
> db.Product.query.options(sao.joinedload_all('variations.channels'), 
> sao.joinedload_all('variations.specifics')).all()
> 
> The second joinedload_all should just have been joinedload. It was causing 
> variations to be included twice in the joinedload, presumably causing a cross 
> product that made the query very slow.
> 
> I can't imagine there's any legitimate need to include a relation twice, so 
> it would be helpful if SQLAlchemy issued an error for this condition.

joinedload()/joinedload_all() against "somekey" essentially puts a token in a 
dictionary that represents "somekey".  It's unique, and there's no mechanism by 
which it would include "variations" as two distinct FROM targets given the form 
you have above.  There shouldn't be any issue saying 
joinedload_all("a.b")/joinedload_all("a.c").

A simple test illustrates this, this works at least as far back as 0.7 if not 
further:

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)
    bs = relationship("B")


class B(Base):
    __tablename__ = 'b'

    id = Column(Integer, primary_key=True)
    a_id = Column(Integer, ForeignKey('a.id'))
    cs = relationship("C")
    ds = relationship("D")

class C(Base):
    __tablename__ = 'c'

    id = Column(Integer, primary_key=True)
    b_id = Column(Integer, ForeignKey('b.id'))

class D(Base):
    __tablename__ = 'd'

    id = Column(Integer, primary_key=True)
    b_id = Column(Integer, ForeignKey('b.id'))

sess = Session()

print sess.query(A).options(joinedload_all("bs.cs"), joinedload_all("bs.ds"))

in the output, we see that "b" is stated as a FROM target only once and is 
present in all three ON clauses:

SELECT a.id AS a_id, c_1.id AS c_1_id, c_1.b_id AS c_1_b_id, d_1.id AS d_1_id, 
d_1.b_id AS d_1_b_id, b_1.id AS b_1_id, b_1.a_id AS b_1_a_id 
FROM a LEFT OUTER JOIN b AS b_1 ON a.id = b_1.a_id LEFT OUTER JOIN c AS c_1 ON 
b_1.id = c_1.b_id LEFT OUTER JOIN d AS d_1 ON b_1.id = d_1.b_id




-- 
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 http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to