提问人:eje211 提问时间:7/25/2010 最后编辑:Mogsdadeje211 更新时间:1/21/2018 访问量:3365
Python 的 mysqldb 晦涩难懂的文档
Python's mysqldb obscure documentation
问:
Python 模块 mysqldb 中有许多转义函数,我不理解它们的文档,我努力查找它们没有发现任何信息。
>>> print _mysql.escape.__doc__
escape(obj, dict) -- escape any special characters in object obj
using mapping dict to provide quoting functions for each type.
Returns a SQL literal string.
这个文档页面说了同样的话。但是,这个“映射词典”中应该包含什么?我尝试了几种(主要是随机的)方法,但只返回错误。更令人沮丧的是,虽然该方法有效,但其文档字符串为:escape_string()
>>> print _mysql.escape_string.__doc__
escape_string(s) -- quote any SQL-interpreted characters in string s.
Use connection.escape_string(s), if you use it at all.
_mysql.escape_string(s) cannot handle character sets. You are
probably better off using connection.escape(o) instead, since
it will escape entire sequences as well as strings.
所以,我最好使用,是吗?嗯,呃......好吧,但是如何?那个“映射词典”到底是什么?至少在这一点上,PHP不那么神秘。_mysql.escape()
答:
2赞
David Z
7/25/2010
#1
实际上,您最好使用更高级别的接口 MySQLdb。(请参阅用户指南)
这些函数实际上只是 C API 的包装器。它们本来就是一个实现细节,这种东西甚至不会出现在PHP的文档中。开发人员故意将它们记录得很少,以阻止人们不必要地使用它们,也因为您可以参考 MySQL C API 文档来获取等效函数,该文档相当完整。_mysql
评论
0赞
eje211
7/25/2010
该文档页面是我首先查找的,但这些_mysql函数是该页面唯一提到的有关转义数据的内容。我清楚地记得小鲍比桌子的可怕案例:<xkcd.com/327>。如果 Little Bobby Tables 出现在我的数据库中怎么办?哦,恐怖!
0赞
David Z
7/25/2010
我知道,MySQLdb 的好处在于,在正常使用中,它会自动为您处理转义,因此当您使用更高级别的接口时,无法获得 SQL 注入。
7赞
unutbu
7/25/2010
#2
我通过查看 /usr/lib/pymodules/python2.6/MySQLdb/connections 了解到这一点.py
看看它是如何称呼的.稍微嗅一嗅就会发现.下面是一个片段:connection.escape
MySQLdb.converters.conversions
{0: <class 'decimal.Decimal'>,
1: <type 'int'>,
...
<type 'dict'>: <built-in function escape_dict>,
<type 'NoneType'>: <function None2NULL at 0xae9717c>,
<type 'set'>: <function Set2Str at 0xae9709c>,
<type 'str'>: <function Thing2Literal at 0xae971b4>,
<type 'tuple'>: <built-in function escape_sequence>,
<type 'object'>: <function Instance2Str at 0xae971ec>,
<type 'unicode'>: <function Unicode2Str at 0xae9710c>,
<type 'array.array'>: <function array2Str at 0xae9725c>,
<type 'bool'>: <function Bool2Str at 0xae97294>}
你可以像这样使用它:
import MySQLdb
import MySQLdb.converters
import datetime
now=datetime.datetime.now()
connection=MySQLdb.connect(
host=HOST,user=USER,passwd=PASS,db=MYDB)
print(connection.escape((1,2,now),MySQLdb.converters.conversions))
# ('1', '2', "'2010-07-24 19:33:59'")
关于Bobby Tables:对于MySQLdb的正常使用,您不必手动转义参数。只需在调用时使用参数化参数,MySQLdb 就会自动为您引用参数。cursor.execute
例如:
sql='insert into students (name,grade,date) values (%s, %s, %s)'
args=("Robert'); DROP TABLE Students; --",60,now) # no manual quotation necessary
cursor=connection.cursor()
cursor.execute(sql,args)
评论
0赞
eje211
7/25/2010
我试着用Little Bobby Tables的名字逃跑,它奏效了。但是,知道自动逃脱也令人放心。它是否在大卫·扎斯拉夫斯基(David Zaslavsky)链接到的文档页面中?我在那里没有看到它......但我可能错过了它。cursor.execute()
0赞
eje211
7/25/2010
如果你读过 XKCD 条带,Bobby Tables 的真名是:“Robert”);DROP TABLE 学生;--".这是一个可怕的名字,可以放入数据库。但是一个很好的测试用例。
0赞
unutbu
7/25/2010
@eje211:您关于文档中解释参数自动报价的问题是一个很好的问题。我能找到的最好的就是看 python.org/dev/peps/pep-0249。The client should not be required to "escape" the value so that it can be used
0赞
Cody
10/23/2015
#3
试试这个mysqldb教程。我自己也用它来学习mysqldb
评论