【问题标题】:SQLAlchemy: Filtering across many-to-many yet returning all resultsSQLAlchemy:过滤多对多但返回所有结果
【发布时间】:2014-08-13 04:30:38
【问题描述】:

从多对多博客和标签模型以及来自Querying a many-to-many relationship in SQLAlchemy 的查询开始,我知道session.query(Blog).join(Blog.tags).options(contains_eager(Blog.tags)).filter(Blog.tags.in_(list_of_relevant_tags)).all() 会给我所有在list_of_relevant_tags 中至少有一个标签的博客文章,以及那些标签将已经被查询并返回。

我看到的潜在问题(我无法对此进行测试)是我是否想获取返回的博客上的标签列表。我想返回所有标签,但生成的 SQL 会建议,充其量,这需要第二个查询。在最坏的情况下,SQLA 将只返回与列表匹配的标签。

有没有办法在 ORM 中提交此查询,以在一个数据库命中返回匹配的博客文章以及 所有 他们的标签?

【问题讨论】:

  • 我不认为你有你害怕的问题。 join 和 filter 将使用完全不同的对象。如果您不舒服,只需为此场景创建一个测试用例即可。

标签: python postgresql python-2.7 sqlalchemy


【解决方案1】:

我想通了。不过,这感觉像是一种解决方法;必须有一种更直接的方法来使用 ORM 做到这一点。

基本上,您使用关联表的子查询(我们称它为BlogTag,列blog_id 和tag_id,分别是blogs.id 和tags.id 的外键)来生成一个列表blog_ids 符合标签标准。然后,您将 blog_ids 的列表内部连接到 Blog 的其他未过滤查询连接到 Tag 以仅返回相关的 Blogs。

t = session.query(BlogTag.blog_id).filter(BlogTag.tag_id.in_(list_of_relevant_tags)).\
    group_by(BlogTag.blog_id).subquery('t')
blogs = session.query(Blog).join(Blog.tags).join(t, t.c.blog_id == Blog.id).\
    options(contains_eager(Blog.tags)).all()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-08-18
    • 1970-01-01
    • 1970-01-01
    • 2020-02-12
    • 2020-11-06
    • 1970-01-01
    • 2013-11-23
    相关资源
    最近更新 更多