it-swarm.com.de

Anwenden von LIMIT und OFFSET auf alle Abfragen in SQLAlchemy

Ich entwerfe eine API mit SQLAlchemy (Abfragen von MySQL) und möchte, dass alle meine Abfragen die Parameter page_size (LIMIT) und page_number (OFFSET) haben.

Gibt es einen sauberen Weg, dies mit SQLAlchemy zu tun? Vielleicht eine Fabrik bauen, um ein benutzerdefiniertes Abfrageobjekt zu erstellen? Oder gibt es eine gute Möglichkeit, dies mit einer Mixin-Klasse zu tun?

Ich habe das Offensichtliche ausprobiert und es hat nicht funktioniert, weil .limit () und .offset () aufgerufen werden müssen, nachdem alle Filterbedingungen angewendet wurden:

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

Wenn ich es versuche, bekomme ich die Ausnahme:

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.
32
Rob Crowell

Fügen Sie ein erstes erforderliches Argument hinzu, das eine Gruppe von Abfragefiltern sein muss. Somit,

# 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

oder,

# 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
32
pydsigner

Zum Zeitpunkt dieser Frage keine Option. Seit Version 1.0.0 können Sie Query events nutzen, um sicherzustellen, dass limit und offset-Methoden immer aufgerufen werden, unmittelbar bevor das query-Objekt kompiliert wird, nachdem die Manipulation durch das System durchgeführt wurde Benutzer Ihrer q-Funktion:

from sqlalchemy.event import listen


def q(page=0, page_size=None):
    query = session.query()
    listen(query, 'before_compile', apply_limit(page, page_size), retval=True)
    return query

def apply_limit(page, page_size):
    def wrapped(query):
        if page_size:
            query = query.limit(page_size)
            if page:
                query = query.offset(page * page_size)
        return query
    return wrapped
0
Daniele