Dynamiczne konstruowanie filtrów w SQLAlchemy
Szukam sposobu na dynamiczne konstruowanie filtrów za pomocą SQLAlchemy. To znaczy, biorąc pod uwagę kolumnę, nazwę operatora i wartość porównawczą, skonstruuj odpowiedni filtr.
Postaram się zilustrować za pomocą przykładu (będzie to wykorzystane do zbudowania API). Powiedzmy, że mamy następujący model:
class Cat(Model):
id = Column(Integer, primary_key=True)
name = Column(String)
age = Column(Integer)
Chciałbym mapować zapytania do filtrów. Na przykład,
/cats?filter=age;eq;3
powinien wygenerowaćCat.query.filter(Cat.age == 3)
/cats?filter=age;in;5,6,7&filter=id;ge;10
powinien wygenerowaćCat.query.filter(Cat.age.in_([5, 6, 7])).filter(Cat.id >= 10)
Rozejrzałem się, aby zobaczyć, jak to zostało zrobione, ale nie mogłem znaleźć sposobu, który nie wymagałby ręcznego mapowania nazwy każdego operatora na komparator lub coś podobnego. Na przykład,Flask-Restless przechowuje słownik wszystkich obsługiwanych operacji i przechowuje odpowiednie funkcje lambda (kod tutaj).
Szukałem w dokumentach SQLAlchemy i znalazłem dwa potencjalne potencjalnych klientów, ale żaden nie wydawał się satysfakcjonujący:
za pomocąColumn.like
, Column.in_
...: te operatory są dostępne bezpośrednio w kolumnie, co ułatwiłoby korzystanie z nichgetattr
ale niektórych nadal brakuje (==
, >
itd.).
za pomocąColumn.op
: np.Cat.name.op('=')('Hobbes')
ale to nie wydaje się działać dla wszystkich operatorów (in
mianowicie).
Czy istnieje czysty sposób, aby to zrobić bezlambda
Funkcje?