如何在 Python3 中将输入转义到 MySQL 数据库?

Posted

技术标签:

【中文标题】如何在 Python3 中将输入转义到 MySQL 数据库?【英文标题】:How can I escape the input to a MySQL db in Python3? 【发布时间】:2012-07-06 23:30:16 【问题描述】:

我正在使用 Pymysql 并且工作正常,但是当我尝试执行以下操作时:

cursor.execute("SELECT * FROM `Codes` WHERE `ShortCode` =  ''".format(request[1]))

如果字符串有'",它将不起作用。我也试过了:

cursor.execute("SELECT * FROM `Codes` WHERE `ShortCode` =  %s",request[1])

问题在于库 (PyMySQL) 使用 Python2.x 的格式化语法 %,这不再有效。 我也找到了这个可能的解决方案

conn.escape_string()

在here,但我不知道在哪里添加这段代码。 这就是我得到的全部:

import pymysql
import sys
conn = pymysql.connect( host   = "localhost",
            user   = "test",
            passwd = "",
            db     = "test")
cursor = conn.cursor()
cursor.execute("SELECT * FROM `Codes` WHERE `ShortCode` =  ".format(request[1]))

result = cursor.fetchall()

cursor.close()
conn.close()

编辑:我解决了!在 PyMySQL 中正确的做法是这样的:

import pymysql
import sys
conn = pymysql.connect(host="localhost",
            user="test",
            passwd="",
            db="test")
cursor = conn.cursor()
text = conn.escape(request[1])
cursor.execute("SELECT * FROM `Codes` WHERE `ShortCode` =  ".format(text))

cursor.close()
conn.close()

text = conn.escape(request[1]) 行是转义代码的地方。在 PyMySQL 代码中找到它。在那里,request[1] 是输入。

【问题讨论】:

酷。不过,您应该发布问题的后半部分作为答案。您可以接受自己的答案。 糟糕,我之前没看到那个按钮。 如果已解决,则将您自己的问题标记为已接受。 :-) @Jocelyn 它告诉我“你可以在 11 小时内接受你自己的答案”,所以我稍后再试。 【参考方案1】:

虽然“已解决”的答案有效,但这不是最佳做法。当使用符合 Python DBI 的库时,您应该使用绑定变量而不是格式化字符串并将其传递给执行。这种方法存在固有的危险。

因此,这是正确的做法:

cursor.execute("SELECT * FROM `Codes` WHERE `ShortCode` = %s", text)

请注意,这不是格式字符串,而是传递给执行光标的绑定变量。

详情:Python DBI PEP

【讨论】:

请注意,即使是整数等不同类型,也应使用“%s”。我尝试使用 '%d' 并收到错误:%d format: a number is required, not str 尝试将其用于批量插入,但最终一次执行一行。主要疼痛【参考方案2】:

解决了。在 PyMySQL 中正确的做法是这样的:

import pymysql
import sys
conn = pymysql.connect(host="localhost",
            user="test",
            passwd="",
            db="test")
cursor = conn.cursor()
text = conn.escape(request[1])
cursor.execute("SELECT * FROM `Codes` WHERE `ShortCode` =  ".format(text))

cursor.close()
conn.close()

text = conn.escape(request[1]) 行是转义代码的地方。在 PyMySQL 代码中找到它。在那里,request[1] 是输入。

【讨论】:

直接使用.format 的做法非常糟糕——@rootsmith 的回答是正确的方法,因为它会进行消毒。【参考方案3】:

准备使用辅助函数

def mysql_insert(conn, table, row):
    cols = ', '.join('``'.format(col) for col in row.keys())
    vals = ', '.join('%()s'.format(col) for col in row.keys())
    sql = 'INSERT INTO `0` (1) VALUES (2)'.format(table, cols, vals)
    conn.cursor().execute(sql, row)
    conn.commit()

使用示例

insert_into(conn, 'people', 
    'firstname': 'John',
    'lastname': 'Doe',
    'age': 18, )

参考:https://github.com/PyMySQL/PyMySQL/blob/master/pymysql/cursors.py#L157-L158

def execute(self, query, args=None):

如果 args 是一个列表或元组,%s 可以用作查询中的占位符。
如果 args 是 dict,则 %(name)s 可以用作查询中的占位符。

【讨论】:

以上是关于如何在 Python3 中将输入转义到 MySQL 数据库?的主要内容,如果未能解决你的问题,请参考以下文章

当我通过 JSON 获取输入时,如何在 Ibatis 中将 java.util.Date 映射到 MySql Date

如何在 .NET Core 中将 JSON 序列化为没有转义字符的字符串?

CMD命令中的参数带有双引号,如何转义双引号?

如何在 python3 中将 OrderedDict 转换为常规字典

在python3中将日期值存储到sqlite表中

如何匹配保存在 mysql 表中的“\a's”等转义字符?