gpt4 book ai didi

python - SQLAlchemy 急切加载多个关系

转载 作者:太空狗 更新时间:2023-10-29 21:31:02 25 4
gpt4 key购买 nike

SQLAlchemy 支持关系的预加载,它基本上是一个 JOIN 语句。但是,如果一个模型有两个或多个关系,它可能是一个非常大的连接。例如,

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

这个查询的性能真的很差,因为OrderTagJOIN会生成一个巨大的表。但是OrderTag在这里没有任何关系,所以他们不应该是JOIN。它应该是两个单独的查询。因为 session 有一定程度的缓存,所以我将查询更改为此。

session.query(Product).join(Product.order) \
.options(joinedload(Product.tags)).all()

q = session.query(Product).join(User.addresses) \
.options(joinedload(Product.cases)).all()

这次的表现要好得多。但是,我不认为这样做是正确的。我不确定 session 结束时标签的缓存是否会过期。

请告诉我这种查询的合适方式。谢谢!

最佳答案

对于一对多或多对多关系,(通常)最好使用 subqueryload相反,出于性能原因:

session.query(Product).join(User.addresses)\
.options(subqueryload(Product.orders),\
subqueryload(Product.tags)).all()

这会为每个 orderstags 发出单独的 SELECT 查询。

关于python - SQLAlchemy 急切加载多个关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34886407/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com