Skip to content

Instantly share code, notes, and snippets.

@pawl
Last active March 9, 2017 07:07
Show Gist options
  • Save pawl/0c7d6db1e7e86ca0b271b5a3ac85ce7f to your computer and use it in GitHub Desktop.
Save pawl/0c7d6db1e7e86ca0b271b5a3ac85ce7f to your computer and use it in GitHub Desktop.
zen of eager loading
from sqlalchemy import create_engine, Column, ForeignKey, Integer
from sqlalchemy.orm import relationship, scoped_session, sessionmaker
from sqlalchemy.ext.declarative import declarative_base
engine = create_engine('mysql://root@localhost/test?charset=utf8mb4',
convert_unicode=True)
session = scoped_session(sessionmaker(autocommit=False,
autoflush=False,
bind=engine))
Base = declarative_base()
Base.query = session.query_property()
class Post(Base):
__tablename__ = 'posts'
id = Column(Integer, primary_key=True)
products = relationship(
'Product',
lazy='joined',
)
class Product(Base):
__tablename__ = 'products'
id = Column(Integer, primary_key=True)
post_id = Column(Integer, ForeignKey('posts.id'), index=True)
#Base.metadata.drop_all(engine)
Base.metadata.create_all(engine)
# add rows for testing
first_result = Post.query.first()
if not first_result:
for x in range(50):
products = [Product() for y in range(12)]
session.add(Post(products=products))
session.commit()
# causes subquery (see The Zen of Eager Loading in SQLAlchemy docs)
print(Product.query.limit(20))
# solution?
ids = session.query(Product.id).limit(20)
Product.query.filter(Product.id.in_(ids))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment