将LIMIT和OFFSET应用于SQLAlchemy中的所有查询

时间:2012-11-06 20:34:04

标签: python sqlalchemy api-design

我正在使用SQLAlchemy设计API(查询MySQL),我想强制所有查询都有page_size(LIMIT)和page_number(OFFSET)参数。

使用SQLAlchemy有一种干净的方法吗?也许构建某种工厂来创建自定义Query对象?或者也许有一个很好的方法来使用mixin类吗?

我尝试了显而易见的事情并且它没有用,因为在应用了所有过滤条件后必须调用.limit()和.offset():

def q(page=0, page_size=None):
    q = session.query(...)
    if page_size: q = q.limit(page_size)
    if page: q = q.offset(page*page_size)
    return q

当我尝试使用它时,我得到了例外:

sqlalchemy.exc.InvalidRequestError: Query.filter() being called on a Query which already has LIMIT or OFFSET applied. To modify the row-limited results of a  Query, call from_self() first.  Otherwise, call filter() before limit() or offset() are applied.

3 个答案:

答案 0 :(得分:34)

尝试添加第一个必需参数,该参数必须是一组查询过滤器。因此,

# q({'id': 5}, 2, 50)
def q(filters, page=0, page_size=None):
    query = session.query(...).filter_by(**filters)
    if page_size:
        query = query.limit(page_size)
    if page: 
        query = query.offset(page*page_size)
    return query

,或者

# q(Model.id == 5, 2, 50)
def q(filter, page=0, page_size=None):
    query = session.query(...).filter(filter)
    if page_size:
        query = query.limit(page_size)
    if page: 
        query = query.offset(page*page_size)
    return query

答案 1 :(得分:0)

在提出此问题时,这不是一个选择,因为自1.0.0版开始,您可以利用Query events来确保limitoffset方法总是在您的{{ {} {1}}函数的用户执行任何操作后,将编译1}}对象:

query

答案 2 :(得分:0)

您可以调用query.limit(None).删除以前应用的限制或偏移。