I am looking for a way to dynamically construct filters using SQLAlchemy. That is, given the column, the operator name and the comparing value, construct the corresponding filter.
I'll try to illustrate using an example (this would be used to build an API). Let's say we have the following model:
class Cat(Model):
id = Column(Integer, primary_key=True)
name = Column(String)
age = Column(Integer)
I would like to map queries to filters. For example,
/cats?filter=age;eq;3
should generate Cat.query.filter(Cat.age == 3)
/cats?filter=age;in;5,6,7&filter=id;ge;10
should generate Cat.query.filter(Cat.age.in_([5, 6, 7])).filter(Cat.id >= 10)
I looked around to see how it has been done but couldn't find a way that didn't involve manually mapping each operator name to a comparator or something similar. For instance, Flask-Restless keeps a dictionary of all supported operations and stores the corresponding lambda functions (code here).
I searched in the SQLAlchemy docs and found two potential leads but neither seemed satisfying:
using Column.like
, Column.in_
...: these operators are available directly on the column which would make it simple using getattr
but some are still missing (==
, >
, etc.).
using Column.op
: e.g. Cat.name.op('=')('Hobbes')
but this doesn't seem to work for all operators (in
namely).
Is there a clean way to do this without lambda
functions?
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…