mysqldb python 转义?还是 %s?
我现在正在使用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 个回答
你可以使用三重引号和原始字符串格式。
self.cur.execute(r"""SELECT dist FROM distance ... """,...)
如果我没记错的话,你不需要手动对你的unicode字符串进行编码。mysqldb模块会帮你处理这个问题。
而且,mysqldb模块使用%s
作为参数,而不是?
。这就是你第一个例子出错的原因。
更具体地说,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 字符串……插值……即使是在枪口下。