【发布时间】:2014-11-09 05:35:11
【问题描述】:
我的查询似乎为每个封面返回 1 个条目。也就是说,如果我在数据库中有 3 个封面,那么查询将使用每个不同的封面返回条目 #1 三次。因为我有 7 个条目,所以我得到了 21 个结果。如何构建查询以返回与条目关联的封面?
这是我所拥有的:
@app.route('/list', methods=['GET', 'POST'])
def list():
entries = Book.query.order_by(Book.id.desc()).all()
cvr_entries = Cover.query.filter(Cover.book).all()
### Other queries I've tried ###
# cvr_entries = Cover.query.join(Cover.book).all()
# cvr_entries = Cover.query.filter(Cover.book.any())
# cvr_entries = Cover.query.filter(Cover.book.any()).all()
return render_template(
'list.html',
entries=entries,
cvr_entries=cvr_entries)
这是/list 输出页面:
{% for entry in entries %}
{% for cvr in cvr_entries %}
<article class="entry">
<img src="/static/data/covers/{{ cvr.name }}" alt="Cover for {{ entry.title }}" />
<ul class="entry-info">
<li class=""><h2>{{ entry.title }}</h2></li>
<li class="">Summary: {{ entry.summary|truncate( 30, true ) }}</li>
</ul>
</article>
{% endfor %}
{% endfor %}
切换 entries 和 cvr_entries for 循环的顺序不会改变任何事情。我也尝试添加first() 而不是all(),但这会导致显示错误
TypeError: 'Cover' object is not iterable
所以这是一个半身像。我不明白如何构建查询。
这是我的模型,应@jonafato 的要求:
book_to_cover = db.Table('book_to_cover',
db.Column('cover_id', db.Integer, db.ForeignKey('cover.id')),
db.Column('book_id', db.Integer, db.ForeignKey('book.id'))
)
class Book(db.Model):
__tablename__ = 'book'
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String())
summary = db.Column(db.Text)
book_to_cover = db.relationship('Cover', secondary=book_to_cover,
backref=db.backref('book', lazy='dynamic'))
def __repr__(self):
return "<Book (title='%s')>" % (self.title)
class Cover(db.Model):
__tablename__ = 'cover'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String())
def __repr__(self):
return "<Cover (name='%s')>" % self.name
【问题讨论】:
-
你能发布你的 SQLAlchemy 模型吗?特别是,您是否在
Book和Cover之间定义了关系(带有反向引用)?如果是这样,您应该能够完全删除cvr_entries查询并将您的内部for循环更改为类似于{% for cvr in entry.covers %}。 -
除了我之前的评论,您可以使用
joinedload来防止循环内不必要的查询。 -
@jonafato 我试过
cvr_entries = Cover.query.options(joinedload(Cover.book)),但我得到了NameError: global name 'joinedload' is not defined。我也尝试了entry.covers方法,但根本没有返回任何条目。 -
必须先从
sqlalchemy.orm导入joinedload才能使用。 -
我导入它并得到错误
InvalidRequestError: 'Cover.book' does not support object population - eager loading cannot be applied.我找到了一个解决方案here,但这不起作用。我还将我的加载从dynamic更改为joined无济于事。
标签: database flask flask-sqlalchemy