Skip to content

Instantly share code, notes, and snippets.

@jdavcs
Created April 4, 2021 16:42
Show Gist options
  • Save jdavcs/01bc51625c493f2bd193d3dfd450fcd1 to your computer and use it in GitHub Desktop.
Save jdavcs/01bc51625c493f2bd193d3dfd450fcd1 to your computer and use it in GitHub Desktop.
SA deferred load possible bug / basic demo
from sqlalchemy import (
create_engine,
inspect,
Column,
ForeignKey,
Integer
)
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import (
defer,
joinedload,
relationship,
sessionmaker,
subqueryload,
)
Base = declarative_base()
class Parent(Base):
__tablename__ = 'parent'
id = Column(Integer, primary_key=True)
stuff = Column(Integer)
children = relationship('Child', back_populates='parent')
class Child(Base):
__tablename__ = 'child'
id = Column(Integer, primary_key=True)
parent_id = Column(Integer, ForeignKey('parent.id'))
parent = relationship('Parent', back_populates='children')
def load(session):
p = Parent()
c = Child()
p.children.append(c)
session.add_all([p, c])
def run(session):
result = session.query(Parent).options(
defer(Parent.stuff),
joinedload('children').subqueryload('parent').options(
defer(Parent.stuff))
).one()
insp = inspect(result)
print('callables:', insp.callables)
assert 'stuff' in insp.callables, 'deferred `Parent.stuff` should be available as a callable'
engine = create_engine('sqlite:///:memory:', echo=True)
Base.metadata.create_all(engine)
Session = sessionmaker(bind=engine)
session = Session()
load(session)
run(session)
session.close()
# # 1.3.23
# SELECT parent.id AS parent_id, child_1.id AS child_1_id, child_1.parent_id AS child_1_parent_id
# FROM parent
# LEFT OUTER JOIN child AS child_1 ON parent.id = child_1.parent_id
#
# SELECT parent.id AS parent_id, child_1.parent_id AS child_1_parent_id
# FROM (SELECT parent.id AS parent_id FROM parent) AS anon_1
# JOIN child AS child_1 ON anon_1.parent_id = child_1.parent_id
# JOIN parent ON parent.id = child_1.parent_id
#
# # 1.4.5
# SELECT parent.id AS parent_id, child_1.id AS child_1_id, child_1.parent_id AS child_1_parent_id
# FROM parent
# LEFT OUTER JOIN child AS child_1 ON parent.id = child_1.parent_id
#
# SELECT parent.id AS parent_id, parent.stuff AS parent_stuff, child_1.parent_id AS child_1_parent_id
# FROM (SELECT parent.id AS parent_id FROM parent) AS anon_1
# JOIN child AS child_1 ON anon_1.parent_id = child_1.parent_id
# JOIN parent ON parent.id = child_1.parent_id
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment