Python/ PonyORM /MySQL - 使用多个 URL 参数进行查询
Python/ PonyORM /MySQL - Query using multiple URL Args
我有一个URLhttps://example.com?p1=nai&p2=tex&p3=mak
我在 MYSQL 上使用 PONY ORM + Flask。我想获取与 URL 参数匹配的所有行。 p1、p2 和 p3 是 table 上的字段,可能会因用户输入而异
在 MySQL 我会做类似的事情 [SELECT * FROM Table Name WHERE p1=nai&p2=tex]
下面是我的 PONY/Flask 代码
query = select(r for r in Route)
for key,value in args.items():
query = query.where("lambda r: r.%s == '%s'" %(key, value))
print(r.id)
我上面的查询只是 return 第一个参数的匹配项。即如果 p1 = nai 那么它将 return 所有 p1= nai 并忽略其余部分。我错过了什么?注意:不要担心 SQL 注入
您可以将请求参数与 python 的 **kwargs 功能一起使用。假设我们想在我们的用户数据库中寻找一个名为 bob 的人,他今年 22 岁:
http://127.0.0.1:5000/?name=bob&age=22
您可以像这样将请求参数转换为字典:
argumentdict = request.args.to_dict()
然后您可以使用 kwargs
查询我们的用户
users = User.query.filter_by(**argumentdict).all()
与以下内容相同:
users = User.query.filter_by(name='bob', age='22').all()
然后会将所有姓名为 bob 且年龄为 22 岁的用户放入列表中。
完整的代码片段:
from flask import Flask, render_template, request, render_template_string
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
db = SQLAlchemy(app)
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String)
age = db.Column(db.Integer)
db.create_all()
for name, age in [['Bob', 45], ['John', 55], ['Bob', 22]]:
user = User()
user.name = name
user.age = age
db.session.add(user)
db.session.commit()
@app.route("/")
def index():
argumentdict = request.args.to_dict()
users = User.query.filter_by(**argumentdict).all()
print(users)
app.run()
使用此查询:http://127.0.0.1:5000/?name=bob&age=22
,将打印:
[<User 3>]
不过,当它与无效的请求参数一起使用时,它会给您带来错误 (name=bob&age=22&country=russia)
,因此您必须考虑到这一点。
编辑:我完全错过了 PONY ORM 位,对此感到抱歉。我对此一无所知,但如果您可以使用与 SQL-Alchemy (column1=value1, column2=value2, ...) 中相同的方式进行查询,那么它也应该适用于此示例。无论如何我都会把它留在这里,因为它对那些使用 SQL-Alchemy 的人仍然有用。
如果你想使用 PonyORM 通过精确匹配来过滤参数,你可以为 filter
或 where
方法指定关键字参数:
kwargs = {'name': 'John', 'age': 20}
query = Route.select().where(**kwargs)
对于更复杂的查询,可以使用 getattr
:
for name, value in kwargs.items():
query = query.where(lambda r: getattr(r, name) == value)
My query above just returns a match for the first parameter.
我怀疑这是由您的代码中的某些错误引起的,也许您将新查询分配给 query2
然后使用以前的 query
而不是 query2
。
注意
kwargs = {'name': 'John', 'age': 20})
query = Register.select().where(**kwargs)
resp= []
for r in query:
resp.append({"id":r.id,.,...............)
return jsonify(resp)
Alexander 的上述回答是正确的,但只会 return 1 个响应。您可能必须创建一个 python 数组并在查询结果中追加多个值。
我有一个URLhttps://example.com?p1=nai&p2=tex&p3=mak
我在 MYSQL 上使用 PONY ORM + Flask。我想获取与 URL 参数匹配的所有行。 p1、p2 和 p3 是 table 上的字段,可能会因用户输入而异
在 MySQL 我会做类似的事情 [SELECT * FROM Table Name WHERE p1=nai&p2=tex]
下面是我的 PONY/Flask 代码
query = select(r for r in Route)
for key,value in args.items():
query = query.where("lambda r: r.%s == '%s'" %(key, value))
print(r.id)
我上面的查询只是 return 第一个参数的匹配项。即如果 p1 = nai 那么它将 return 所有 p1= nai 并忽略其余部分。我错过了什么?注意:不要担心 SQL 注入
您可以将请求参数与 python 的 **kwargs 功能一起使用。假设我们想在我们的用户数据库中寻找一个名为 bob 的人,他今年 22 岁:
http://127.0.0.1:5000/?name=bob&age=22
您可以像这样将请求参数转换为字典:
argumentdict = request.args.to_dict()
然后您可以使用 kwargs
查询我们的用户users = User.query.filter_by(**argumentdict).all()
与以下内容相同:
users = User.query.filter_by(name='bob', age='22').all()
然后会将所有姓名为 bob 且年龄为 22 岁的用户放入列表中。
完整的代码片段:
from flask import Flask, render_template, request, render_template_string
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
db = SQLAlchemy(app)
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String)
age = db.Column(db.Integer)
db.create_all()
for name, age in [['Bob', 45], ['John', 55], ['Bob', 22]]:
user = User()
user.name = name
user.age = age
db.session.add(user)
db.session.commit()
@app.route("/")
def index():
argumentdict = request.args.to_dict()
users = User.query.filter_by(**argumentdict).all()
print(users)
app.run()
使用此查询:http://127.0.0.1:5000/?name=bob&age=22
,将打印:
[<User 3>]
不过,当它与无效的请求参数一起使用时,它会给您带来错误 (name=bob&age=22&country=russia)
,因此您必须考虑到这一点。
编辑:我完全错过了 PONY ORM 位,对此感到抱歉。我对此一无所知,但如果您可以使用与 SQL-Alchemy (column1=value1, column2=value2, ...) 中相同的方式进行查询,那么它也应该适用于此示例。无论如何我都会把它留在这里,因为它对那些使用 SQL-Alchemy 的人仍然有用。
如果你想使用 PonyORM 通过精确匹配来过滤参数,你可以为 filter
或 where
方法指定关键字参数:
kwargs = {'name': 'John', 'age': 20}
query = Route.select().where(**kwargs)
对于更复杂的查询,可以使用 getattr
:
for name, value in kwargs.items():
query = query.where(lambda r: getattr(r, name) == value)
My query above just returns a match for the first parameter.
我怀疑这是由您的代码中的某些错误引起的,也许您将新查询分配给 query2
然后使用以前的 query
而不是 query2
。
注意
kwargs = {'name': 'John', 'age': 20})
query = Register.select().where(**kwargs)
resp= []
for r in query:
resp.append({"id":r.id,.,...............)
return jsonify(resp)
Alexander 的上述回答是正确的,但只会 return 1 个响应。您可能必须创建一个 python 数组并在查询结果中追加多个值。