Hello! We noticed some weird behavior where our tests were affecting one 
another, and I tracked it down to what I believe is a SQLAlchemy bug. It 
appears that performing a particular query with a joinedload can alter 
future queries that are run without the same joinedload. This appears to 
only happen when using 'polymorphic_load': 'selectin' (and not with 
'inline'):

from benchling import db

### Table setup
class Parent(db.Model):
    __tablename__ = 'parent'
    id = db.Column(db.Integer, primary_key=True)


class Child(db.Model):
    __tablename__ = 'child'
    id = db.Column(db.Integer, primary_key=True)
    parent_id = db.Column(db.Integer, db.ForeignKey('parent.id'))
    parent = db.relationship('Parent', backref=db.backref('children'))

    type = db.Column(db.String(), nullable=False)
    __mapper_args__ = {
        'polymorphic_on': type,
    }

class ChildSubclass1(Child):
    __tablename__ = 'child_subclass1'
    id = db.Column(db.Integer, db.ForeignKey('child.id'), primary_key=True)
    __mapper_args__ = {'polymorphic_identity': 'subclass1', 
'polymorphic_load': 'selectin'}


class Other(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    child_subclass_id = db.Column(db.Integer, 
db.ForeignKey('child_subclass1.id'))
    child_subclass = db.relationship('ChildSubclass1', 
backref=db.backref('others'))

Parent.__table__.create(bind=db.engine)
Child.__table__.create(bind=db.engine)
ChildSubclass1.__table__.create(bind=db.engine)
Other.__table__.create(bind=db.engine)


def is_other_in_session():
    return any(isinstance(model, Other) for model in db.session)


### Bug repro:
parent = Parent()
subclass1 = ChildSubclass1(parent=parent)
other = Other(child_subclass=subclass1)
db.session.add_all([parent, subclass1, other])
db.session.commit()


# Test 1: Loading Parent + Children does not load Other
print '\nTest #1: Loading Parent + Children does not load others'
db.session.expunge_all()
assert not is_other_in_session()
parents = 
Parent.query.options(db.joinedload(Parent.children.of_type(ChildSubclass1))).all()
assert not is_other_in_session()

print '\nTest #2: Loading Parent + Children + Others loads others as 
expected'
db.session.expunge_all()
assert not is_other_in_session()
parents = 
Parent.query.options(db.joinedload(Parent.children.of_type(ChildSubclass1)).joinedload(ChildSubclass1.others)).all()
assert is_other_in_session()

print '\nTest #3: Loading Parent + Children should not load others, but it 
does now'
db.session.expunge_all()
assert not is_other_in_session()
parents = 
Parent.query.options(db.joinedload(Parent.children.of_type(ChildSubclass1))).all()
assert not is_other_in_session(), 'The above query should not load any 
Others!'

Test #1 and Test #3 are identical, but Test #3 fails because it is run 
after Test #2 (which does a joinedload on ChildSubclass.others). I thought 
this might be related to baked queries, but it still fails 
with enable_baked_queries=False . Let me know if there's any other 
information I can provide that would be useful, or if there are any 
workarounds we can use right now!

-- 
SQLAlchemy - 
The Python SQL Toolkit and Object Relational Mapper

http://www.sqlalchemy.org/

To post example code, please provide an MCVE: Minimal, Complete, and Verifiable 
Example.  See  http://stackoverflow.com/help/mcve for a full description.
--- 
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 [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.

Reply via email to