我一直在试图弄清楚如何将request.args传递给sqlalchemy过滤器。
我认为这应该有效:
model.query.filter(**request.args).all()
但它正在抛出错误:
TypeError: <lambda>() got an unexpected keyword argument 'userid'
当存在userid或任何其他get arg时。
根据这篇文章 - https://stackoverflow.com/questions/19506105/flask-sqlalchemy-query-with-keyword-as-variable - 你可以将一个字典传递给过滤函数。
任何想法我做错了什么?
非常感谢:)
更新:非常感谢下面的海报,但是现在它引发了以下错误:
ProgrammingError: (ProgrammingError) (1064, "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ') ORDER BY tblclients.clientname' at line 3") 'SELECT favourites.id AS favourites_id, favourites.userid AS favourites_userid, favourites.clientid AS favourites_clientid, favourites.last_visit AS favourites_last_visit \nFROM favourites INNER JOIN tblclients ON tblclients.clientid = favourites.clientid \nWHERE favourites.userid = %s ORDER BY tblclients.clientname' ([u'41'],)
有什么想法吗?
答案 0 :(得分:8)
首先,您必须使用filter_by
,而不是filter
。
其次,Flask request.args
使用MultiDict,一个带有列表中值的dict,允许同一个键有多个值,因为同一个字段在查询字符串中可以出现多次。您收到错误是因为SQL查询得到[u'41']
时只能预期'41'
。您可以使用request.args.to_dict()
来解决此问题:
model.query.filter_by(**request.args.to_dict()).all()
答案 1 :(得分:4)
使用filter_by
:
model.query.filter_by(**request.args).all()
filter
的使用方式如下:query.filter(Class.property == value)
而filter_by
的使用方式如下:query.filter_by(property=value)
(第一个是表达式,后一个是关键字参数)
答案 2 :(得分:1)
filter_by(**request.args)
如果你有非模型查询参数,例如page
用于分页,则效果不佳,否则会出现以下错误:
InvalidRequestError: Entity '<class 'flask_sqlalchemy.JobSerializable'>' has no property 'page'
我使用类似这样的东西来忽略不在模型中的查询参数:
builder = MyModel.query
for key in request.args:
if hasattr(MyModel, key):
vals = request.args.getlist(key) # one or many
builder = builder.filter(getattr(MyModel, key).in_(vals))
if not 'page' in request.args:
resources = builder.all()
else:
resources = builder.paginate(
int(request.args['page'])).items
考虑一个名为valid
的列的模型,这样的东西会起作用:
curl -XGET "http://0.0.0.0/mymodel_endpoint?page=1&valid=2&invalid=whatever&valid=1"
invalid
将被忽略,page
可用于分页,最重要的是,将生成以下SQL:WHERE mymodel.valid in (1,2)
(如果您使用此boilerplate-saving module)
,请免费获取上述代码段