My question from stackoverflow: 
http://stackoverflow.com/questions/20519910/subqueryload-does-not-populate-relation-if-backref-is-joined

Why CASE 4 (see output) does not provide related children. It looks like if 
it happens because subqueryload does not populate relation if backref is 
joinedload. But what logic is behind this? Is it a bug?

Please, note diffence between  these lines:

    children1 = relationship('Child1', back_populates='parent', 
cascade='all', lazy='noload')
    children2 = relationship('Child2', back_populates='parent', 
cascade='all', lazy='noload')
    parent = relationship('Parent', back_populates='children1', 
cascade='all', lazy='joined')
    parent = relationship('Parent', back_populates='children2', 
cascade='all', lazy='subquery')
    
    parent = 
session3.query(Parent).options([joinedload('children1')]).get(1)
    parent = 
session4.query(Parent).options([joinedload('children2')]).get(1)
    parent = 
session5.query(Parent).options([subqueryload('children1')]).get(1)
    parent = 
session6.query(Parent).options([subqueryload('children2')]).get(1)


-------- CODE ---------


    from sqlalchemy import Column, Integer, String, ForeignKey
    from sqlalchemy import create_engine
    from sqlalchemy.orm import relationship, sessionmaker, subqueryload, 
joinedload
    from sqlalchemy.ext.declarative import declarative_base
    
    
    Base = declarative_base()
    
    
    class Parent(Base):
        __tablename__ = 'parent'
    
        id = Column(Integer, primary_key=True)
        name = Column(String(20))
    
        children1 = relationship('Child1', back_populates='parent', 
cascade='all', lazy='noload')
        children2 = relationship('Child2', back_populates='parent', 
cascade='all', lazy='noload')
    
    
    class Child1(Base):
        __tablename__ = 'child1'
    
        id = Column(Integer, primary_key=True)
        name = Column(String(20))
        parent_id = Column(Integer, ForeignKey('parent.id', 
ondelete='CASCADE'))
    
        parent = relationship('Parent', back_populates='children1', 
cascade='all', lazy='joined')
    
        def __repr__(self):
            return repr((self.id, self.name, self.parent_id))
    
    
    class Child2(Base):
        __tablename__ = 'child2'
    
        id = Column(Integer, primary_key=True)
        name = Column(String(20))
        parent_id = Column(Integer, ForeignKey('parent.id', 
ondelete='CASCADE'))
    
        parent = relationship('Parent', back_populates='children2', 
cascade='all', lazy='subquery')
    
        def __repr__(self):
            return repr((self.id, self.name, self.parent_id))
    
    
    engine = create_engine('sqlite:///:memory:')
    Base.metadata.create_all(engine)
    Session = sessionmaker(bind=engine)
    
    session1 = Session()
    session1.add(Parent(id=1, name='parent'))
    session1.add(Child1(id=1, name='child1_1', parent_id=1))
    session1.add(Child1(id=2, name='child1_2', parent_id=1))
    session1.add(Child2(id=1, name='child2_1', parent_id=1))
    session1.add(Child2(id=2, name='child2_2', parent_id=1))
    session1.commit()
    session1.expunge_all()
    session1.close()
    
    session2 = Session()
    parent = session2.query(Parent).get(1)
    print 'CASE 1 (no options):', parent.id, parent.children1, 
parent.children2
    session2.close()
    
    session3 = Session()
    parent = 
session3.query(Parent).options([joinedload('children1')]).get(1)
    print 'CASE 2 (joined vs joinedload):', parent.id, parent.children1
    session3.close()
    
    session4 = Session()
    parent = 
session4.query(Parent).options([joinedload('children2')]).get(1)
    print 'CASE 3 (subquery vs joinedload):', parent.id, parent.children2
    session4.close()
    
    session5 = Session()
    parent = 
session5.query(Parent).options([subqueryload('children1')]).get(1)
    print 'CASE 4 (joined vs subqueryload):', parent.id, parent.children1
    session5.close()
    
    session6 = Session()
    parent = 
session6.query(Parent).options([subqueryload('children2')]).get(1)
    print 'CASE 5 (subquery vs subqueryload):', parent.id, parent.children2
    session6.close()

Output

    CASE 1 (no options): 1 [] []
    CASE 2 (joined vs joinedload): 1 [(1, u'child1_1', 1), (2, u'child1_2', 
1)]
    CASE 3 (subquery vs joinedload): 1 [(1, u'child2_1', 1), (2, 
u'child2_2', 1)]
    CASE 4 (joined vs subqueryload): 1 []
    CASE 5 (subquery vs subqueryload): 1 [(1, u'child2_1', 1), (2, 
u'child2_2', 1)]




-- 
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