Python 的 mysqldb 晦涩难懂的文档

Python's mysqldb obscure documentation

提问人:eje211 提问时间:7/25/2010 最后编辑:Mogsdadeje211 更新时间:1/21/2018 访问量:3365

问:

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()

Python MySQL

评论


答:

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.escapeMySQLdb.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-0249The client should not be required to "escape" the value so that it can be used
0赞 unutbu 7/25/2010
MySQLdb.converters.conversion这里也解释了:mysql-python.sourceforge.net/......
0赞 Cody 10/23/2015 #3

试试这个mysqldb教程。我自己也用它来学习mysqldb