提问人:Brodario 提问时间:10/2/2019 更新时间:10/2/2019 访问量:1782
Python 将单引号添加到我的查询参数
Python adds single quote to my query parameters
问:
我正在尝试执行查询:
SELECT '23.34.67.0/22' CONCAT(DAY_31, 'hello') DAY_31 FROM Jule
使用 pymysql。我的代码是:
cursor.execute("SELECT %s CONCAT(%s, %s) %s FROM Jule", (p, 'DAY_' + _day, as_tmp, 'DAY_' + _day))
但是 python 添加了单引号并返回语法错误
“你的 SQL 语法有误;查看与您的MySQL服务器版本相对应的手册,了解在第1行的'('DAY_31', 'hello') 'DAY_31' FROM Jule'附近使用的正确语法”
DAY_31 是 Jule Schema 的一列
答:
如果没记错的话,代替可能会解决问题。?
%s
评论
实际上正在发生的事情与.这只是您在 python 中格式化字符串的方式。cursor.execute
我们首先应该注意 %s %d 可以特定于 SQL,并且这些也可以在 python 中用于字符串格式化。
因此,考虑到这一点,我认为您没有必要使用 %s 进行字符串格式设置(这无助于提高可读性)。由于您直接访问数据库,因此您可以直接在 python 中格式化字符串。cursor.execute
小检查一下发生了什么:
p = "23.34.67.0/22"
as_tmp = "hello"
_day = "3"
print("SELECT %s CONCAT(%s, %s) %s FROM Jule", (p, 'DAY_' + _day, as_tmp, 'DAY_' + _day))
# output
# SELECT %s CONCAT(%s, %s) %s FROM Jule ('23.34.67.0/22', 'DAY_3', 'hello', 'DAY_3')
# ^^^^ so this is what is being sent in cursor.execute (with all the quotes and so on)
如果你用 f 字符串格式化,你会增加可读性,你应该摆脱引号的问题
print(f"SELECT '{p}' CONCAT(DAY_{_day}, '{as_tmp}') DAY_{_day} FROM Jule")
# output
# SELECT '23.34.67.0/22' CONCAT(DAY_3, 'hello') DAY_3 FROM Jule
因此,解决方案可能是:
cursor.execute(f"SELECT '{p}' CONCAT(DAY_{_day}, '{as_tmp}') DAY_{_day} FROM Jule")
评论
as_tmp
你最终得到引号的原因是,在你作为参数传入的值周围添加这些引号。这完全适用于您的第二个参数,因为如果按原样将值“hello”插入到查询中,您最终会得到如下查询:cursor.execute
SELECT '23.34.67.0/22' CONCAT(DAY_31, hello) DAY_31 FROM Jule
并且您会错误地告诉您MySQL无法识别应该引用的内容。hello
显然,这不适用于要传入字段名称或查询中不是基元字符串值的任何其他部分的情况。在这些情况下,您需要在执行查询之前将它们拼接到字符串中。一种方法是使用 f 字符串,但也有其他选择。这是使用 f 字符串拼接的字段名称的行:cursor.execute
cursor.execute(f"SELECT %s, CONCAT({'DAY_'+_day}, %s) {'DAY_'+_day} FROM Jule", (p, as_tmp))
请注意,我也已从参数列表中删除了 。'DAY_'+_day
重要提示:
虽然这应该像这样工作(尽管我认为您还需要一个额外的逗号,我在上面的示例中添加了逗号),但非常重要的一点是,如果有一个来自应用程序外部的值(例如,由用户在表单字段中传入),请确保它在将其拼接到查询之前完全采用您想要的格式。检查字符串值是否为整数可能是执行此操作的一种方法。它之所以重要,是因为如果没有它,您的应用程序可能容易发生 SQL 注入,这可能会允许用户在您的数据库上运行任意 SQL。如果 的值仅由应用程序计算,则无需担心此问题。SELECT '23.34.67.0/22'
day
day
评论
SELECT '23.34.67.0/22', CONCAT(DAY_31, 'hello'), DAY_31 FROM Jule