I have 2 classes, User and Address (i tried to make my test case resemble 
the contents 
of 
http://docs.sqlalchemy.org/en/latest/orm/loading_relationships.html#contains-eager),
 
defined like this:


from sqlalchemy import *
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import *


e = create_engine('sqlite:////tmp/test.db', echo=True)
Base = declarative_base()
Base.metadata = MetaData(e)

class User(Base):
   __tablename__ = 'user'
   id = Column(Integer, primary_key=True)
   addresses = relationship("Address")

class Address(Base):
   __tablename__ = 'address'
   id = Column(Integer, primary_key=True)
   user_id = Column(Integer, ForeignKey(User.id))

I am populating the db with this:

if __name__ == '__main__':
    Base.metadata.drop_all()
    Base.metadata.create_all()

    address1 = Address()
    address2 = Address()
    address3 = Address()
    user = User(id=1, addresses=[address1, address2])

    session = Session(e)
    session.add(user, address3)
    session.commit()


I can use this query to get expected results:

q = session.query(User) \
        .filter(User.id==1) \
        .first()
    print q.addresses
    # [<__main__.Address object at 0x7f93bf5e46d0>, <__main__.Address 
object at 0x7f93bf5e4710>]

The sql for this is (in sqlite, although the issue occurs in mysql as well, 
but with a slightly different query):

SELECT user.id AS user_id 
FROM user 
WHERE user.id = 1
 LIMIT 1 OFFSET 0


this attempt, however, includes a 'limit 1' which is restricting the 
addresses to 1:

q = session.query(User) \
        .outerjoin(User.addresses) \
        .options(contains_eager(User.addresses)) \
        .filter(User.id==1) \
        .first()
    print q.addresses
    # [<__main__.Address object at 0x7f93bf5a3fd0>]

the sql:

SELECT address.id AS address_id, address.user_id AS address_user_id, 
user.id AS user_id 
FROM user LEFT OUTER JOIN address ON user.id = address.user_id 
WHERE user.id = 1
 LIMIT 1 OFFSET 0

to make it work, I am currently doing this:
q = session.query(User) \
        .outerjoin(User.addresses) \
        .options(contains_eager(User.addresses)) \
        .filter(User.id==1) \
        .all()
if q:
    q = q[0]


This works, but seems kind of dirty. Is this the best way for me to do 
this? What do I need to change in order to have contains_eager populate all 
related objects instead of just the first one?

-- 
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/d/optout.

Reply via email to