python - SQLAlchemy:joinedload 子条款查询的 order_by(无)?

标签 python postgresql sqlalchemy

我们在 Python 2.7.7 和 Postgres 9.3 上使用 SQLAlchemy 0.9.8。

我们有一个查询,它使用 joinedloads 使用单个查询完全填充一些 Recipe 对象。该查询创建了一个大型 SQL 语句,需要 20 秒才能执行 - 太长了。这是 rendered SQL statement on Pastebin .

呈现的 SQL 有一个 ORDER BY 子句,Postgres 解释说这是 99% 的时间花在这个查询上的来源。这似乎来自 ORM 模型中的关系,它有一个 order_by 子句。

但是,我们不关心此查询返回结果的顺序 - 我们只关心查看单个对象时的顺序。如果我在呈现的 SQL 语句末尾删除 ORDER BY 子句,查询将在不到一秒的时间内执行 - 完美。

我们尝试在查询中使用 .order_by(None),但这似乎没有效果。 ORDER BY 似乎与 joinedloads 有关,因为如果将 joinedloads 更改为 lazyloads,它们就会消失。但是我们需要联合负载来提高速度。

如何让 SQLAlchemy 省略 ORDER BY 子句?


仅供引用,这是查询:

missing_recipes = cls.query(session).filter(Recipe.id.in_(missing_recipe_ids)) if missing_recipe_ids else []

这是 ORM 类的摘录:

class Recipe(Base, TransactionalIdMixin, TableCacheMixin, TableCreatedModifiedMixin):
    __tablename__ = 'recipes'
      authors = relationship('RecipeAuthor', cascade=OrmCommonClass.OwnedChildCascadeOptions,
                           single_parent=True,
                           lazy='joined', order_by='RecipeAuthor.order', backref='recipe')
    scanned_photos = relationship(ScannedPhoto, backref='recipe', order_by="ScannedPhoto.position")
    utensils = relationship(CookingUtensil, secondary=lambda: recipe_cooking_utensils_table)
    utensil_labels = association_proxy('utensils', 'name')

我们的 query() 方法看起来像这样(省略了更多的 joinedloads):

@classmethod
def query(cls, session):
    query = query.options(
        joinedload(cls.ingredients).joinedload(RecipeIngredient.ingredient),
        joinedload(cls.instructions),
        joinedload(cls.scanned_photos),
        joinedload(cls.tags),
        joinedload(cls.authors),
    )

最佳答案

[从我在邮件列表上的回答中复制]

您要么需要从 relationship() 中删除 order_by,如果排序不重要,这可能是最好的主意,或者跳过 joinedload(),自己写出连接并使用 contains_eager()(http://docs.sqlalchemy.org/en/rel_0_9/orm/loading_relationships.html?highlight=contains_eager#contains-eager)。

joinedload() 是一种宏,它创建连接和对查询的其他修改(例如 ORDER BY 关系),对每个部分应用别名,这样它们就不会与查询中的任何内容发生冲突,然后将这些额外的 FROM 子句中的列路由到集合和相关对象中。 contains_eager() 只做最后一部分。在这种情况下,前两部分,即编写连接和排序以及可能为它们添加别名(或不添加别名)由您决定,因此您可以完全控制查询的呈现方式。

关于python - SQLAlchemy:joinedload 子条款查询的 order_by(无)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27712919/

相关文章:

PHP (Laravel 4) 和 PostgreSQL 搜索

c# - 如何将 C# 与 Postgres 连接起来?

SQLAlchemy bool 值与 bool 值

python - SQLAlchemy 生成错误的 SQL(对于别名和自连接)?

python - 导入错误 : No module named sqlalchemy

Python:在当前目录及其所有父目录中搜索文件

python - 当我们仅从该模块调用函数时,是否会导入模块顶部的包

python - 在python中自动同步两个录音

python - 更改 KML 中的标签 ID 属性 (Simplekml)

node.js - 将 Async/Await 与 node-postgres 一起使用