【问题标题】:Pattern for rest query params in flask烧瓶中其余查询参数的模式
【发布时间】:2020-02-08 05:15:37
【问题描述】:

在烧瓶休息服务器中是否有处理查询参数的模式?我知道我可以在 python 中使用字符串操作逐字创建 sql 查询词,但我发现这很难看且容易出错,我想知道是否有更好的方法。这是我所拥有的:

param1 = request.args.get('param1', type = int)
param2 = request.args.get('param2', type = int)

if param1 is not None:
    if param2 is not None:
        cursor.execute("SELECT * FROM table WHERE p1 = %s AND p2 = %s", (str(param1), str(param2)))
    else:
        cursor.execute("SELECT * FROM table WHERE p1 = %s", (str(param1),))
else:
    if param2 is not None:
        cursor.execute("SELECT * FROM table WHERE p2 = %s", (str(param2),))
    else:
        cursor.execute("SELECT * FROM table")

很容易看出,可能的 SQL 语句的数量是参数数量的 2 倍,这超出了控制范围……所以,再次,在不使用字符串操作来自定义构建 sql 查询的情况下,是否有成语或模式用于以更优雅的方式完成此任务?谢谢。

【问题讨论】:

  • 请不要通过破坏您的帖子为他人增加工作量。通过在 Stack Exchange (SE) 网络上发帖,您已根据 CC BY-SA license 授予 SE 分发内容的不可撤销权利(即无论您未来的选择如何)。根据 SE 政策,分发非破坏版本。因此,任何破坏行为都将被撤销。请参阅:How does deleting work? …。如果允许删除,则帖子下方左侧有一个“删除”按钮,但仅在浏览器中,而不是移动应用程序中。

标签: mysql sql rest flask flask-restful


【解决方案1】:

遍历你的参数。

params = []
for i in range(1, HoweverManyParamsYouNeed):
    params.append(request.args.get('param' + str(i), type = int))

s = ""
for i in range(1, len(params)):
    if params[ i ] is not None:
        if not s:
            s = "p" + str(i) + " = " + str(params[ i ])
        else:
            s = s + " AND p"  + str(i) + " = " + str(params[ i ])

full = "SELECT * FROM table"
if s:
    full = full + " WHERE " + s
cursor.execute(full)

您可能需要更正此代码,因为我无法运行它。

【讨论】:

  • '任意数量的参数'意味着您必须动态创建至少部分查询。不,没有更好的办法。
【解决方案2】:

我建议使用 ORM(https://en.wikipedia.org/wiki/Object-relational_mapping) 而不是原始的 sql 查询。

    class MyModel(db.Model):
        id = db.Column(db.Integer, primary_key=True)
        column1 = db.Column(db.Integer)
        column2 = db.Column(db.Integer)
  • 假设您在某处查找过滤器
    allowed_filters = {"column1", "column2"}

  • 最后,您可以使用 SQLAlchemy 的 ORM 来代替游标来检索过滤后的对象。
    query = MyModel.query
    for field, value in request.args.items():
        if field in allowed_filters:
            query = query.filter(getattr(MyModel, field) == value)
    my_object_list = list(query.all())

如果您真的想手动创建查询,您可以随时迭代 args:

    where_clause = ""
    params = []
    for field, value in request.args.items():
        if field in allowed_filters:
            if len(where_clause) > 0:
                where_clause += " AND "
            where_clause += "{} = %s".format(field)
            params.append(value)
    if len(where_clause) > 0:
        cursor.execute("SELECT * FROM table WHERE {}".format(where_clause), tuple(params))
    else:
        cursor.execute("SELECT * FROM table")

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-09-26
    • 2017-09-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-27
    相关资源
    最近更新 更多