Construyendo dinámicamente filtros en SQLAlchemy
Estoy buscando una manera de construir filtros dinámicamente usando SQLAlchemy. Es decir, dada la columna, el nombre del operador y el valor de comparación, construya el filtro correspondiente.
Intentaré ilustrar usando un ejemplo (esto se usaría para construir una API). Digamos que tenemos el siguiente modelo:
class Cat(Model):
id = Column(Integer, primary_key=True)
name = Column(String)
age = Column(Integer)
Me gustaría mapear las consultas a los filtros. Por ejemplo,
/cats?filter=age;eq;3
debe generarCat.query.filter(Cat.age == 3)
/cats?filter=age;in;5,6,7&filter=id;ge;10
debe generarCat.query.filter(Cat.age.in_([5, 6, 7])).filter(Cat.id >= 10)
Miré a mi alrededor para ver cómo se había hecho, pero no pude encontrar una manera que no implicara asignar manualmente el nombre de cada operador a un comparador o algo similar. Por ejemplo,Matraz Inquieto mantiene un diccionario de todas las operaciones compatibles y almacena las funciones lambda correspondientes (código aquí).
Busqué en los documentos de SQLAlchemy y encontré dos pistas potenciales, pero ninguna me pareció satisfactoria:
utilizandoColumn.like
, Column.in_
...: estos operadores están disponibles directamente en la columna, lo que simplificaría el uso degetattr
pero algunos todavía faltan (==
, >
, etc.).
utilizandoColumn.op
: p.ej.Cat.name.op('=')('Hobbes')
pero esto no parece funcionar para todos los operadores (in
a saber).
¿Hay una manera limpia de hacer esto sinlambda
funciones?