2012-11-06 8 views
25

SQLAlchemy(MySQLをクエリする)でAPIを設計しています。すべてのクエリにpage_size(LIMIT)パラメータとpage_number(OFFSET)パラメータを強制したいと思います。SQLAlchemyのすべてのクエリにLIMITと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. 
+0

あなたの質問への溶液を編集しないでください。代わりに、下記の別の回答として投稿してください。 – Matt

答えて

25

最初に必要な引数を追加してください。この引数は、クエリフィルタのグループでなければなりません。したがって、

# 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

2つの部分に分割して(Queryオブジェクトを取得し、必須フィルタを適用する)、開発者はすべてのクエリに対してq()を呼び出すことを頼りにします。誰かがall()を呼び出す前にq()を呼び出すことを忘れた場合、結果は引き続き生成されます。 –

+0

次に、クエリではなくフィルタ辞書を使用する必要があります。しかし、これはあなたを幾分制限します。 – pydsigner

+1

@RobCrowell 3年後、これがあなたの問題を解決したのか、何か他のことをやめたのが不思議です(その場合は、あなたが出てきたことについての回答を送ってください)。 – pydsigner

関連する問題