Python MySQLdb TypeError:并非在string格式化过程中转换的所有参数

在运行这个脚本时:

#! /usr/bin/env python import MySQLdb as mdb import sys class Test: def check(self, search): try: con = mdb.connect('localhost', 'root', 'password', 'recordsdb'); cur = con.cursor() cur.execute( "SELECT * FROM records WHERE email LIKE '%s'", search ) ver = cur.fetchone() print "Output : %s " % ver except mdb.Error, e: print "Error %d: %s" % (e.args[0],e.args[1]) sys.exit(1) finally: if con: con.close() test = Test() test.check("test") 

我得到一个错误:

 ./lookup Traceback (most recent call last): File "./lookup", line 27, in <module> test.check("test") File "./lookup", line 11, in creep cur.execute( "SELECT * FROM records WHERE email LIKE '%s'", search ) File "/usr/local/lib/python2.7/dist-packages/MySQLdb/cursors.py", line 187, in execute query = query % tuple([db.literal(item) for item in args]) TypeError: not all arguments converted during string formatting 

我没有理解为什么。 我试图做参数化查询,但这只是一个痛苦。 我对Python有点新鲜,所以这可能是一个明显的问题。

而不是这个:

 cur.execute( "SELECT * FROM records WHERE email LIKE '%s'", search ) 

尝试这个:

 cur.execute( "SELECT * FROM records WHERE email LIKE '%s'", [search] ) 

请参阅MySQLdb 文档 。 原因是execute的第二个参数表示要转换的对象列表,因为在参数化查询中可以有任意数量的对象。 在这种情况下,你只有一个,但它仍然需要一个迭代(一个元组而不是列表也可以)。

你可以试试这个代码:

 cur.execute( "SELECT * FROM records WHERE email LIKE '%s'", (search,) ) 

你可以看到这个文档: http : //mysql-python.sourceforge.net/MySQLdb.html

'%'关键字是非常危险的,因为它是'SQL INJECTION ATTACK'的主要原因。
所以你只是使用这个代码。

 cursor.execute("select * from table where example=%s", (example,)) 

要么

 t = (example,) cursor.execute("select * from table where example=%s", t) 

如果你想尝试插入表,试试这个。

 name = 'ksg' age = 19 sex = 'male' t = (name, age, sex) cursor.execute("insert into table values(%s,%d,%s)", t) 
 cur.execute( "SELECT * FROM records WHERE email LIKE %s", (search,) ) 

我不是为什么,但这对我有用。 而不是使用“%s”“,

我不明白前两个答案。 我认为他们必须是版本依赖的。 我不能在Ubuntu 14.04LTS附带的MySQLdb 1.2.3上重现它们。 我们来试试吧。 首先,我们validationMySQL不接受双撇号:

 mysql> select * from methods limit 1; +----------+--------------------+------------+ | MethodID | MethodDescription | MethodLink | +----------+--------------------+------------+ | 32 | Autonomous Sensing | NULL | +----------+--------------------+------------+ 1 row in set (0.01 sec) mysql> select * from methods where MethodID = ''32''; ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '9999'' ' at line 1 

不。 让我们尝试使用/usr/lib/python2.7/dist-packages/MySQLdb/cursors.py中的查询构造函数强制发布的示例,其中我打开“con”作为连接到我的数据库。

 >>> search = "test" >>> "SELECT * FROM records WHERE email LIKE '%s'" % con.literal(search) "SELECT * FROM records WHERE email LIKE ''test''" >>> 

不,双撇号使它失败。 让我们试试迈克·格雷厄姆的第一个评论,他build议在引用%s的撇号之外:

 >>> "SELECT * FROM records WHERE email LIKE %s" % con.literal(search) "SELECT * FROM records WHERE email LIKE 'test'" >>> 

是的,这将工作,但迈克的第二个评论和文件说,执行的参数(由con.literal处理)必须是一个元组(search,)或列表[search] 。 你可以尝试一下,但是你会发现上面的输出没有什么不同。

最好的答案是ksg97031's。

根据PEP8,我更喜欢以这种方式执行SQL:

 cur = con.cursor() # There is no need to add single-quota to the surrounding of `%s`, # because the MySQLdb precompile the sql according to the scheme type # of each argument in the arguments list. sql = "SELECT * FROM records WHERE email LIKE %s;" args = [search, ] cur.execute(sql, args) 

通过这种方式,您将认识到execute方法的第二个参数args必须是参数列表。

愿这能帮助你。