【问题标题】:Convert a list to comma separated strings for sql IN operator将列表转换为 sql IN 运算符的逗号分隔字符串
【发布时间】:2021-05-13 09:42:20
【问题描述】:

这似乎是非常明显的用例,我很惊讶我找不到任何可行的解决方案。

我有一个方法可以返回类似这样的用户名列表:

username = ["Tom", "Bob", "Charley"]

现在我想用这个变量为 IN 运算符构建一个 sql,类似于:

sql = "Select * from users Where username IN %s" % username;

由于语法错误,上面一行显然失败了。

然后我发现,我可以把它改成元组:

username_tuple = tuple(username)
sql = "Select * from users Where username IN {}".format(username_tuple)

上面的行运行良好,但如果列表中只有一个字符串 (username = ["tom"]),那么它会因语法错误而失败,因为 username_tuple 的计算结果为 ("tom",)(请注意用户名后面的逗号.)

【问题讨论】:

标签: python mysql postgresql


【解决方案1】:

您最终想要的是一个 SQL 字符串,它可以在准备好的语句中使用,然后可以将 username 列表作为参数传递。该字符串看起来像:

Select * from users Where username IN (%s,%s,%s)

并且可以通过以下方式动态构建:

username = ["Tom", "Bob", "Charley"]
params = ','.join(['%s'] * len(username))
sql = f"Select * from users Where username IN ({params})"

然后,您会从您的连接中获得cursor 并执行以下操作:

cursor.execute(sql, username)

通过使用窥视语句,您不必担心转义用户名中可能包含的任何特殊字符,也不必担心 SQL 注入攻击。

【讨论】:

  • 我建议看看SQL
  • @AdrianKlaver psycopg2 适用于 PostgreSQL,但 OP 的问题也标记为 MySQL。
【解决方案2】:

与其重新发明轮子,不如使用来自psycopg2 的内置列表适配。 List adaption:

username = ["Tom", "Bob", "Charley"]
cur.execute("Select * from users Where username = ANY(%s)", [username])

【讨论】:

    【解决方案3】:

    使用str.join()

    sql = "Select * from users Where username IN ({})".format(str(username)[1:-1])
    

    【讨论】:

    • 这导致Select * from users Where username IN (Tom,Bob,Charley)。你觉得这样合适吗?
    猜你喜欢
    • 2013-02-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-04
    • 2023-04-02
    • 2014-08-24
    • 2020-04-04
    • 1970-01-01
    相关资源
    最近更新 更多