向查询结果添加相关列?

时间:2021-02-10 14:59:45

标签: python sqlalchemy flask-sqlalchemy

我在 SQLAlchemy ORM(使用 Flask-SQLAlchemy)中设置了 BookBookSubject 类,后者是多对多关系(当然,{{ 1}} 类,但与此问题无关)。我有一个工作查询,可以根据 subject 添加到数据库的日期返回所有书籍(这是有原因的):

Subject

然后我将 records = Book.query.\ filter(BookSubject.book_id == Book.id).\ filter(BookSubject.subject_id.in_([1, 12, 17])).\ filter(BookSubject.created > '2021-01-01').\ order_by(db.desc(BookSubject.created)).\ paginate(page, 50, True) 传递给 Jinja2 模板并执行各种操作来显示它;它工作得很好。

我现在想做显而易见的事情并实际显示创建日期(即 records,来自 order_by 子句),但我不知道如何将其添加到查询中。输入 BookSubject.created 不是答案;当我尝试使用记录对象之一“'sqlalchemy.util._collections.result object' has no attribute 'id'”时会引发错误。生成它的模板代码(大致)是:

add_columns((BookSubject.created).label("added"))

这应该是显而易见的;我打算如何将其添加到结果中?

1 个答案:

答案 0 :(得分:1)

通过使用 add_columns

Book.query.add_columns((BookSubject.created).label("added"))

它会返回一个带有字段 Bookadded 的命名元组,因此要访问 book 字段,您需要类似 book.Book.id

{% for book in records.items %}
  <tr><td>
     <a href="{{ url_for('fullview', id=book.Book.id) }}">{{ book.Book.title }} {{ book.added }} </a>
  </td></tr>
{% endfor %}

或成对迭代:

{% for book, added in records.items %}
  <tr><td>
     <a href="{{ url_for('fullview', id=book.id) }}">{{ book.title }} {{ added }} </a>
  </td></tr>
{% endfor %}

如果你想要一个扁平的结构(并且没有 add_columns),那么你可以使用

session.query(
  Book.id,
  Book.title,
  BookSubject.created.label('added')
).filter(BookSubject.book_id == Book.id)...

那么结果将有一个命名元组,其中包含字段 idtitleadded,因此您可以直接打印 book.id

{% for book in records.items %}
  <tr><td>
    <a href="{{ url_for('fullview', id=book.id) }}">{{ book.title }} {{ book.added }} </a>
  </td></tr>
{% endfor %}