Je conçois une API avec SQLAlchemy (interroger MySQL) et j'aimerais forcer toutes mes requêtes à avoir les paramètres page_size (LIMIT) et page_number (OFFSET).
Y a-t-il un moyen propre de faire cela avec SQLAlchemy? Peut-être construire une usine pour créer un objet Query personnalisé? Ou peut-être y a-t-il un bon moyen de faire cela avec un cours de mixage?
J'ai essayé la solution évidente et cela n'a pas fonctionné car .limit () et .offset () doivent être appelés après l'application de toutes les conditions de filtrage:
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
Quand j'essaye d'utiliser ceci, j'obtiens l'exception:
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.
Essayez d'ajouter un premier argument requis, qui doit être un groupe de filtres de requête. Ainsi,
# 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
ou,
# 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
Pas une option au moment de cette question, depuis la version 1.0.0, vous pouvez tirer parti de Evénements de requête pour vous assurer que les méthodes limit
et offset
sont toujours appelées juste avant la compilation de votre objet query
, après toute manipulation effectuée par le utilisateurs de votre fonction q
:
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