有没有办法在SQL Alchemy ORM中有条件地为查询添加filter
个参数?
例如,想象一下,我有以下内容:
q = session.query(X)
if a:
q.filter(X.y == 'a')
elif b:
q.filter(X.y == 'a', X.z == 'b')
elif c:
q.filter(X.y == 'a', X.p == 'd')
有没有办法说只需添加
如果X.z == 'b'
,请 b
无需在每个过滤器中读取(X.y == 'a')
。
似乎我可以做到
q.filter(X.y == 'a').filter(X.y == 'b')
但这会更改正在执行的查询。
答案 0 :(得分:10)
尝试将您的查询收集到列表中,然后在致电*
时使用filter
运算符:
queries = [X.y == 'a']
if b:
queries.append(X.z == 'b')
q.filter(*queries)
顺便说一下,我不明白为什么你认为链接两个filter
会改变你的查询,它会对应X.y = a AND X.z = b
,就像你使用filter(X.y == 'a', X.z == 'b')
时一样。
答案 1 :(得分:-1)
我使用 Flask=1.1.2,Flask-SQLAlchemy=2.4.4 e SQLAlchemy-serializer=1.3.4.4
您必须使用 SQLAlchemy 中的 text。
models.py:
from sqlalchemy_serializer import SerializerMixin
from app import db
class Planet(db.Model, SerializerMixin):
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
name = db.Column(db.String, nullable=False)
rotation_period = db.Column(db.String, nullable=True)
orbital_period = db.Column(db.String, nullable=True)
diameter = db.Column(db.String, nullable=True)
climate = db.Column(db.String, nullable=True)
gravity = db.Column(db.String, nullable=True)
terrain = db.Column(db.String, nullable=True)
surface_water = db.Column(db.String, nullable=True)
population = db.Column(db.Integer, nullable=True)
控制器.py
from sqlalchemy.sql import text
from app.planet.models import Planet
class ApiResource(Resource):
@bp.route('/api/planets/')
def get(self):
""" Returns a list of planets """
rows = Planet.query.order_by(Planet.name).all()
# filters
climate = request.args.get('climate', None)
name = request.args.get('name', None)
sort = request.args.get('sort', None)
filters = None
if climate:
filters = "climate='" + climate + "'"
if name:
if filters:
filters += " AND "
filters += "name='" + name + "'"
if filters:
rows = Planet.query.filter(text(filters))
if sort:
rows = rows.order_by(text(sort))
planets = list()
for row in rows:
planets.append(row.to_dict())
return planets
我使用这个包 sqlalchemy_serializer 将查询的结果序列化为一个 json。