query_1 = db\
.Query([UserModel, func.count(FriendModel.friend_id)])\
.select_from(UserModel)\
.outerjoin(FriendModel, and_(UserModel.id==FriendModel.user_id))\
.group_by(FriendModel.user_id)
s_1 = query_1.subquery('s_1')
print s_1.c.id
query_2 = db\
.Query(FriendModel)\
.select_from(FriendModel)\
.outerjoin(s_1, FriendModel.user_id==s_1.c.id)
帮助同时获得两个查询。 https://gist.github.com/vlikin/17d53440eeef7f4147b2
I receive such errors:
InvalidRequestError: SQL expression, column, or mapped entity expected - got '[<sqlalchemy.orm.attributes.InstrumentedAttribute object at 0x7f2e28e1b810>, <sqlalchemy.sql.functions.count at 0x7f2e236c3ed0; count>]'
或
AttributeError: Neither ‘count’ object nor ‘Comparator’ object has an attribute ‘_autoflush’
我也有问题因为db.Query而不是db.session.query。我想使用db.Query,因为它有分页:)
谢谢。
答案 0 :(得分:3)
我遇到了完全相同的问题。
我对此问题的解决方案是直接使用db.session.query
并创建flask_sqlalchemy.Pagination
的新子类。子类包含一个允许我从任何查询创建Pagination
对象的方法。
from flask import abort
from flask_sqlalchemy import Pagination as _Pagination
class Pagination(_Pagination):
"""Extend Pagination class to let us construct it from any BaseQuery."""
@classmethod
def from_query(cls, query, page, per_page, error_out=True):
"""Returns `per_page` items from page `page`. By default it will
abort with 404 if no items were found and the page was larger than
1. This behavor can be disabled by setting `error_out` to `False`.
This is basically a copy of flask_sqlalchemy.Query.paginate()
Returns an :class:`Pagination` object.
"""
if error_out and page < 1:
abort(404)
items = query.limit(per_page).offset((page - 1) * per_page).all()
if not items and page != 1 and error_out:
abort(404)
# No need to count if we're on the first page and there are fewer
# items than we expected.
if page == 1 and len(items) < per_page:
total = len(items)
else:
total = query.order_by(None).count()
return cls(query, page, per_page, total, items)
现在根据以下代码段使用它:
query = db.session.query(…)
pagination = Pagination.from_query(query, page, 20)
首先,问题是从Pagination
创建db.Query
- 对象的主要逻辑不是Pagination类的一部分,而是在db.Query.paginate()
中实现。