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
必须是参数列表。
愿这能帮助你。