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 通过精确匹配来过滤参数,你可以为 filterwhere 方法指定关键字参数:

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 数组并在查询结果中追加多个值。