SQLAlchemy Joinedload过滤列

2024-01-12

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

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 行,这比我预期的要多得多


它不起作用的原因是joinedload(以及所有其他关系加载技术)应该是完全透明的。也就是说有一个joinedload除了导致关系被填充之外,您的查询中不应以任何其他方式影响它。你应该阅读《加入热切加载的禅宗》 https://docs.sqlalchemy.org/en/20/orm/queryguide/relationships.html#the-zen-of-joined-eager-loading,开头为:

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

技巧之一是对不可用的连接表使用别名。然后,您的查询最终会在“工作”和“用户”之间执行隐式交叉联接,从而产生额外的行。因此,为了过滤连接表,请使用Query.join() http://docs.sqlalchemy.org/en/latest/orm/query.html#sqlalchemy.orm.query.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() http://docs.sqlalchemy.org/en/latest/orm/loading_relationships.html#sqlalchemy.orm.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().

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

SQLAlchemy Joinedload过滤列 的相关文章

随机推荐