我正在使用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 )
} )

如果我想查询所有用户,则可以正常工作,并返回带有关联的'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()

在第二个示例中导致失败的原因是因为totalRows = rows.count ()创建了第二个查询来对第一个结果进行计数:SELECT count(1) AS count_1 FROM user,但是当将having插入查询中时,它更改为SELECT count(1) AS count_1 FROM user having booksCount>4,这很容易出错,因为在第二个查询中从未选择booksCount。

那么,如何在应用了having子句的情况下从选择中提取总行呢?

谢谢。

最佳答案

这实际上是sql语法错误。仅当您还包括having子句时,才使用group by子句,并且仅过滤汇总结果。您需要的是一个简单的where子句,该子句可通过以下方式实现:

rows = User.query.filter(User.booksCount > 4)

附带说明:请按照python标准执行代码,例如User.books_count

关于python - sqlalchemy分页,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/6282534/

10-16 11:35