Starting from the many-to-many Blog and Tag model and query from Querying a many-to-many relationship in SQLAlchemy , I know that session.query(Blog).join(Blog.tags).options(contains_eager(Blog.tags)).filter(Blog.tags.in_(list_of_relevant_tags)).all()
will give me all the blog posts that have at least one of the tags in list_of_relevant_tags
, and those tags will already have been queried and returned.
The potential problem I see (I'm having trouble testing this) is if I want to get a list of the tags on the returned Blogs. I want to return all the tags, but the generated SQL would suggest that, at best, this would require a second query. At worst, SQLA will only return the tags that matched the list.
Is there a way to submit this query in the ORM to return the matching blog posts along with all their tags in one database hit?
I figured something out. It feels like a workaround, though; there's gotta be a more direct way to do this with the ORM.
Basically, you use a subquery of the association table (let's call it BlogTag
with columns blog_id
and tag_id
, that are foreign keys to blogs.id
and tags.id
, respectively) to generate a list of blog_id
s that meet the tag criteria. You then inner join that list of blog_id
s to an otherwise-unfiltered query of Blog
joined to Tag
to return just the relevant Blog
s.
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()
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.