我正在使用 Flask 和 sqlalchemy 构建 REST 应用程序,但遇到了一个问题。我想查询所有用户的图书数量。每个用户都有很多书,所以我的查询应该返回每个用户在结果集中拥有的书数。
// Models
class User( object ):
__tablename__ = 'user'
class Book( object ):
__tablename__ = 'book'
// Metadata
users_table = Table( 'user', metadata,
Column( 'id', Integer, primary_key = True ),
Column( 'username', String( 50 ), unique = True )
)
books_table = Table( 'book', metadata,
Column( 'id', Integer, primary_key = True ),
Column( 'title', String( 50 ) ),
Column( 'user_id', Integer, ForeignKey( 'user.id' ) )
)
// Mappers
mapper( User, users_table, properties = {
'booksCount': column_property(
select(
[func.count( books_table.c.id )],
books_table.c.user_id == users_table.c.id
).label( 'booksCount' )
),
'books' : relationship( Book )
} )
mapper( Book, books_table, properties = {
'user': relationship( User )
} )
Run Code Online (Sandbox Code Playgroud)
如果我想查询所有用户,它工作正常并带回相关联的“booksCount”的结果,但如果我想更深入,假设只查询“booksCount”大于 4 的用户它变得复杂,因为我也在应用限制/偏移量之前需要知道总结果计数,以便我的分页工作。
// this works
rows = User.query
totalRows = rows.count ()
users = rows.limit( 50 ).offset( 0 ).all()
for user in users:
...
// this throws an error
rows = User.query.having('booksCount>4')
totalRows = rows.count ()
users = rows.limit( 50 ).offset( 0 ).all()
Run Code Online (Sandbox Code Playgroud)
在第二个示例中失败的原因是因为totalRows = rows.count ()
创建了第二个查询来计算第一个结果:SELECT count(1) AS count_1 FROM user
但是当having
插入到查询中时,它会更改为SELECT count(1) AS count_1 FROM user having booksCount>4
which obvioulsy 引发错误,因为在第二个查询中从未选择过 booksCount。
那么如何在having
应用了子句的选择上提取总行数呢?
谢谢。
我将用相同情况下其他所有人的解决方案来回答我自己的问题。如果您在 ubuntu 上并从存储库安装了 sqlalchemy,请将其卸载并转到 sqlalchemy 网站并按照其安装说明进行操作。新版本(0.7.1 atm)修复了这个错误。
Ubuntu 附带 0.6.4 版本。