我有以下情况:
class Author(Base):
__tablename__ = 'author'
id = Column(Integer, primary_key = True)
name = Column(String)
books = relationship('Books', backref='author')
class Book(Base):
__tablename__ = 'book'
id = Column(Integer, primary_key = True)
title = Column(String)
我想要做的是加载所有拥有包含SQL的书籍的作者 标题。即。
authors = session.query(Author)\
.join(Author.books)\
.filter(Book.title.like('%SQL%')\
.all()
似乎很简单。
我想做的是迭代作者并展示他们的作品 图书。我希望在访问作者[0] .books时,它只会返回 在其标题中包含“SQL”的书籍。但是,我正在分配所有书籍 那个作者。过滤器应用于作者列表,但不适用于作者列表 我访问这段关系的书籍。
如何构建我的查询,以便过滤关系(即 书籍),当我去访问这种关系时,仍然会应用过滤?
答案 0 :(得分:3)
请阅读Routing Explicit Joins/Statements into Eagerly Loaded Collections。然后使用contains_eager
,您可以构建查询并获得您想要的内容:
authors = (
session.query(Author)
.join(Author.books)
.options(contains_eager(Author.books)) # tell SA that we load "all" books for Authors
.filter(Book.title.like('%SQL%'))
).all()
请注意,您实际上是在欺骗sqlalchemy认为它已加载了Author.books
的所有集合,因此您的会话将知道false
有关世界真实状态的信息的
答案 1 :(得分:1)
简而言之,这是不可能的。 (如果是,Author
实例将具有不同的books
属性,具体取决于查询的方式,这没有意义。)
你可以做的是查询反向关系:
books = session.query(Book) \
.filter(Book.title.like('%SQL%')) \
.all()
然后,您可以访问每本书上的.author
来收集同一作者所写的书籍。