mysqldb python 转义?还是 %s?

4 投票
3 回答
5802 浏览
提问于 2025-04-15 20:41

我现在正在使用mysqldb。

在mysqldb的参数中,正确的字符串转义方法是什么呢?

注意,我的连接设置了字符集为'utf8',用的代码是 E = lambda x: x.encode('utf-8')

我在使用这些参数时遇到了错误: w1, w2 = u'你好', u'我好'

self.cur.execute("SELECT dist FROM distance WHERE w1=? AND w2=?", (E(w1), E(w2)))
ret = self.cur.execute("SELECT dist FROM distance WHERE w1=? AND w2=?", (E(w1), E(w2)))

错误信息是:“在执行时,字符串格式化过程中并不是所有参数都被转换。” 这个错误出现在文件 "build/bdist.linux-i686/egg/MySQLdb/cursors.py" 的第158行。

self.cur.execute("SELECT dist FROM distance WHERE w1=%s AND w2=%s", (E(w1), E(w2)))

虽然这样做没问题,但如果w1或w2里面有反斜杠(\),那么转义就明显失败了。

我个人知道,使用%s来传递参数并不是一个好方法,因为它容易受到注入攻击等问题。

3 个回答

0

你可以使用三重引号和原始字符串格式。

self.cur.execute(r"""SELECT dist FROM distance ... """,...)
1

如果我没记错的话,你不需要手动对你的unicode字符串进行编码。mysqldb模块会帮你处理这个问题。

而且,mysqldb模块使用%s作为参数,而不是?。这就是你第一个例子出错的原因。

4

更具体地说,cursor.execute() 这个方法可以接受一个可选的参数,这个参数包含了需要被引号包裹并插入到 SQL 模板或语句中的值。这个过程并不是简单地用 % 操作符来完成的!也就是说,cursor.execute(some_sql, some_params)cursor.execute(some_sql % some_params)不一样 的。

Python DB-API 规定,任何符合标准的驱动程序或模块都必须提供一个 .paramstyle 属性,这个属性可以是 'qmark'、'numeric'、'named'、'format' 或 'pyformat' 中的任何一种……这样理论上你就可以通过检查和稍微调整你的 SQL 查询字符串,使其适应支持的格式。这样做应该比自己手动将值引号包裹并插入到 SQL 字符串中要安全得多。

我看到 PsycoPG 文档中有一句话让我觉得特别有趣:警告:绝对不要,绝对不要,绝对不要使用 Python 字符串……插值……即使是在枪口下。

撰写回答