sqlalchemy pagination - PullRequest
       3

sqlalchemy pagination

4 голосов
/ 08 июня 2011

Я создаю REST-приложение с флягой и sqlalchemy, и я столкнулся с проблемой. Я хочу опросить всех пользователей с их количеством книг. У каждого пользователя много книг, поэтому в моем запросе должно быть указано количество книг каждого пользователя в наборе результатов.

//      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()

Причина этого сбоя во 2-м примере заключается в том, что 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?

Спасибо.

Ответы [ 2 ]

2 голосов
/ 09 июня 2011

На самом деле это синтаксическая ошибка sql. Предложение having используется только в том случае, если включено предложение group by и только фильтрация агрегированных результатов. Вам нужно простое предложение where, которое достигается с помощью:

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

в качестве примечания: пожалуйста, делайте ваш код в соответствии со стандартами Python, например, User.books_count

0 голосов
/ 09 июня 2011

Я собираюсь ответить на свой вопрос с решением для всех остальных в той же ситуации. Если вы используете Ubuntu и установили sqlalchemy из репозитория, удалите его и перейдите на сайт sqlalchemy и следуйте инструкциям по установке. В новой версии (0.7.1 атм) эта ошибка исправлена.

Ubuntu поставляется с версией 0.6.4.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...