SQLAlchemy ansioso por cargar múltiples relaciones
SQLAlchemy admite una carga ansiosa por una relación, es básicamente unJOIN
declaración. Sin embargo, si un modelo tiene dos o más relaciones, podría ser una unión muy grande. Por ejemplo,
class Product(Base):
__tablename__ = 'product'
id = Column(Integer, primary_key=True, autoincrement=True)
name = Column(String(255), nullable=False)
orders = relationship('Order', backref='product', cascade='all')
tags = relationship('Tag', secondary=product_tag_map)
class Order(Base):
__tablename__ = 'order'
id = Column(Integer, primary_key=True, autoincrement=True)
date = Column(TIMESTAMP, default=datetime.now())
class Tag(Base):
__tablename__ = 'tag'
id = Column(Integer, primary_key=True, autoincrement=True)
tag_type = Column(String(255), nullable=False)
tag_value = Column(String(255), nullable=False)
q = session.query(Product).join(User.addresses)\
.options(joinedload(Product.orders))\
.options(joinedload(Product.tags)).all()
El rendimiento de esta consulta es realmente malo, porque elJOIN
deOrder
yTag
generará una gran mesa. Pero elOrder
yTag
no tiene ninguna relación aquí, por lo que no deberían serJOIN
. Deben ser dos consultas separadas. Y debido a que la sesión tiene cierto nivel de almacenamiento en caché, cambié mi consulta a esto.
session.query(Product).join(Product.order) \
.options(joinedload(Product.tags)).all()
q = session.query(Product).join(User.addresses) \
.options(joinedload(Product.cases)).all()
Esta vez el rendimiento es mucho mejor. Sin embargo, no estoy convencido de que esto sea lo correcto. No estoy seguro de que las memorias caché de las etiquetas expiren cuando finalice la sesión.
Por favor, hágame saber la forma adecuada para este tipo de consulta. ¡Gracias!