【问题标题】:SQLAlchemy Joinedload filter columnSQLAlchemy Joinedload 过滤器列
【发布时间】:2017-11-11 22:22:11
【问题描述】:

您好,我想使用joinedload 对我的查询进行过滤。但我似乎无法让它工作。以下是我的示例查询

result = (
        session.query(Work).
        options(
            joinedload(Work.company_users).
            joinedload(CompanyUser.user)
        ).
        filter(Work.id == 1).
        filter(User.first_name == 'The name').  <<--- I can't get this to work.
        all()
    )

运行它时,它返回的行超出了我的预期。真正的结果应该只返回 8 行。但在执行此查询时,它返回 234 行,这比我预期的要多

【问题讨论】:

    标签: python sqlalchemy


    【解决方案1】:

    它不起作用的原因是joinedload(以及所有其他关系加载技术)是完全透明的。也就是说,在您的查询中包含 joinedload 不应该以任何其他方式影响它,除非导致关系被填充。你应该阅读"The Zen of Joined Eager Loading",它的开头是:

    由于加入的急切加载似乎与Query.join() 的使用有很多相似之处,它经常会在何时以及如何使用它时产生混淆。重要的是要理解Query.join() 用于更改查询结果的区别,joinedload() 竭尽全力不更改查询结果,而是隐藏渲染连接的效果,只允许以显示相关对象。

    其中一个技巧是对不可用的连接表使用别名。然后,您的查询最终会在 Work 和 User 之间执行隐式交叉连接,因此会产生额外的行。所以为了过滤一个连接的表,使用Query.join():

    session.query(Work).\
        join(Work.company_users).\
        join(CompanyUser.user).\
        filter(Work.id == 1).\
        filter(User.first_name == 'The name').\
        all()
    

    如果您还需要预先加载,您可以指示查询它已经包含与contains_eager() 的连接:

    session.query(Work).\
        join(Work.company_users).\
        join(CompanyUser.user).\
        options(contains_eager(Work.company_users).
                contains_eager(CompanyUser.user)).\
        filter(Work.id == 1).\
        filter(User.first_name == 'The name').\
        all()
    

    注意对contains_eager() 的链式调用。

    【讨论】:

      【解决方案2】:

      好的,我明白了。对于那些可能解决相同问题的人,我所做的是将joinedload 替换为 contains_eager 并添加了一个连接。下面是修改代码

      result = (
          session.query(Work)
          .join(Work.company_users)
          .join(CompanyUser.user)
          .options(
              contains_eager(Work.company_users)
              .contains_eager(CompanyUser.user)
          )
          .filter(Work.id == 1)
          .filter(User.first_name == 'The name')  # <<--- Now this to works.
          .all()
      )
      

      【讨论】:

        猜你喜欢
        • 2013-08-18
        • 1970-01-01
        • 2011-03-20
        • 1970-01-01
        • 2015-01-15
        • 2012-05-03
        • 2016-09-17
        • 2017-01-17
        • 2015-03-31
        相关资源
        最近更新 更多