Python的MySQLdb的类型错误:不是所有的参数字符串转换期间格式化
在运行此脚本:Python的MySQLdb的类型错误:不是所有的参数字符串转换期间格式化
#! /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的documentation。原因在于execute
的第二个参数表示要转换的对象的列表,因为您可以在参数化查询中拥有任意数量的对象。在这种情况下,你只有一个,但它仍然需要是一个可迭代的(一个元组而不是一个列表也可以)。
我明白了,所以必须通过一个列表才能使其工作? –
另外有趣的是,我仍然可以在输入中传递%,它不会转义它,而是会像通配符一样使用它 –
@MandatoryProgrammer不会使用'%'格式化查询字符串。使用上面的方法。并从文档'的DB API要求你作为一个序列传递任何参数。' –
你可以试试这个代码:
cur.execute("SELECT * FROM records WHERE email LIKE '%s'", (search,))
你可以看到the documentation
在元组末尾添加逗号正是我所需要的。 – User
您不应该在占位符周围手动引用。 –
'%' 的关键字是非常危险的,因为 'SQL注入攻击' 的是主要原因。
所以你只是使用这段代码。
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)
我不明白前两个答案。我认为他们必须是版本依赖的。我无法在Ubuntu 14.04LTS附带的MySQLdb 1.2.3上重现它们。让我们尝试一下。首先,我们验证MySQL不接受双撇号:
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''"
>>>
不,双撇号导致它失败。让我们尝试迈克·格雷厄姆的第一个评论,他建议离开过撇号引述%S:
>>> "SELECT * FROM records WHERE email LIKE %s" % con.literal(search)
"SELECT * FROM records WHERE email LIKE 'test'"
>>>
是的,这将工作,但麦克的第二意见和文档说参数执行(由CON处理。文字)必须是一个元组(search,)
或列表[search]
。你可以尝试它们,但你会发现上面的输出没有什么不同。
最好的答案是ksg97031's。
ksg97031也使用元组。这与MySQLdb库相关,而不是MySQL本身。 – adonese
cur.execute("SELECT * FROM records WHERE email LIKE %s", (search,))
我不是为什么,但这对我有用。而不是使用'%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
必须的参数列表。
愿这帮助你。
不需要/希望引用您的查询参数。 –
即'cur.execute(“SELECT * FROM records WHERE email LIKE%s”,[search])' –
我在使用python2.7时遇到了这个问题,但是在使用python2.6时是正确的。你知道原因吗? – Matt