【问题标题】:Reducing duplicate JOIN clauses produced by SQLAlchemy减少 SQLAlchemy 产生的重复 JOIN 子句
【发布时间】:2013-08-18 15:59:02
【问题描述】:

我目前无法找到减少由 SQLAlchemy 急切加载产生的多余 JOIN 子句的方法。我目前正在查询TableA,它急切地加载TableB,而TableB 急切地加载TableC

我的查询还包含 显式 连接到 TableBTableC 以便过滤这些表的列。但是,它会产生如下的详细 SQL:

  SELECT * FROM TableA 
           JOIN TableB             ON TableA.fk == TableB.id
           JOIN TableC             ON TableB.fk == TableC.id
LEFT OUTER JOIN TableB AS TableB_1 ON TableA.fk == TableB.id
LEFT OUTER JOIN TableC AS TableC_1 ON TableB.fk == TableC.id

我目前在反向引用上使用lazy='joined' 以从TableA 查询中急切地加载TableBTableC。使用子查询加载此数据会产生 N+1 选择问题(因此不能从急切加载切换到延迟加载)。

我还尝试将innerjoin=True 添加到反向引用,它用内部连接替换了LEFT OUTER JOIN 子句(输出中只是JOIN)。我希望 SQLAlchemy 能够合并相同的连接子句,但似乎没有。

有没有办法在查询或关系上指定不应重复相同的连接子句?

【问题讨论】:

    标签: join sqlalchemy


    【解决方案1】:

    你能告诉我们代码吗?不清楚你到底在做什么。

    要从显式连接中急切地填充关系集合,您应该使用contains_eager 选项而不是joinedload。即

    from sqlalchemy.orm import contains_eager, joinedload
    
    session.query(ModelA).join(ModelB).options(contains_eager(ModelA.bs_list)).all()
    

    相对

    session.query(ModelA).join(ModelB).options(joinedload(ModelA.bs_list)).all()
    

    【讨论】:

    • 谢谢。我忽略了关系文档中的contains_eager 部分。这正是我想要的。
    猜你喜欢
    • 1970-01-01
    • 2015-06-21
    • 2013-08-11
    • 1970-01-01
    • 1970-01-01
    • 2016-02-18
    • 2020-09-19
    • 2017-10-07
    相关资源
    最近更新 更多