运行此脚本时:
#! /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有些新意,所以这可能是一个明显的问题。
答案 0 :(得分:76)
而不是:
cur.execute( "SELECT * FROM records WHERE email LIKE '%s'", search )
试试这个:
cur.execute( "SELECT * FROM records WHERE email LIKE %s", [search] )
请参阅MySQLdb documentation。原因是execute
的第二个参数表示要转换的对象列表,因为在参数化查询中可以有任意数量的对象。在这种情况下,你只有一个,但它仍然需要是一个可迭代的(一个元组而不是一个列表也可以)。
答案 1 :(得分:16)
您可以尝试以下代码:
cur.execute( "SELECT * FROM records WHERE email LIKE '%s'", (search,) )
您可以看到the documentation
答案 2 :(得分:2)
cur.execute( "SELECT * FROM records WHERE email LIKE %s", (search,) )
我不知道为什么,但这对我有用。而不是使用'%s'
。
答案 3 :(得分:0)
我不理解前两个答案。我认为它们必须依赖于版本。我无法在MySQLdb 1.2.3上重现它们,它随Ubuntu 14.04LTS一起提供。我们来试试吧。首先,我们验证MySQL不接受双撇号:
/usr/lib/python2.7/dist-packages/MySQLdb/cursors.py
不。让我们尝试使用>>> search = "test"
>>> "SELECT * FROM records WHERE email LIKE '%s'" % con.literal(search)
"SELECT * FROM records WHERE email LIKE ''test''"
>>>
里面的查询构造函数强制发布的示例,其中我打开了#34; con&#34;作为我数据库的连接。
>>> "SELECT * FROM records WHERE email LIKE %s" % con.literal(search)
"SELECT * FROM records WHERE email LIKE 'test'"
>>>
不,双撇号导致它失败。让我们试试Mike Graham的第一条评论,他建议不要引用撇号来引用%s:
(search,)
是的,这会有效,但Mike的第二条评论和文档说要执行的参数(由con.literal处理)必须是元组[search]
或列表{{1}} 。你可以尝试一下,但是你发现上面的输出没有区别。
最好的答案是ksg97031&#39。
答案 4 :(得分:0)
根据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)
通过这种方式,您将认识到args
方法的第二个参数execute
必须是参数列表。
这可以帮助你。
答案 5 :(得分:0)
@ kevinsa5接受的答案是正确的,但您可能会想“我发誓此代码使用可以正常工作,但现在不起作用,”您是正确的。
MySQLdb库在1.2.3和1.2.5之间进行了API更改。支持的1.2.3版本
cursor.execute("SELECT * FROM foo WHERE bar = %s", 'baz')
但是1.2.5版本需要
cursor.execute("SELECT * FROM foo WHERE bar = %s", ['baz'])
作为其他答案的状态。我在变更日志中找不到更改,很可能以前的行为被认为是错误。
Ubuntu 14.04存储库具有python-mysqldb 1.2.3,但Ubuntu 16.04和更高版本具有python-mysqldb 1.3.7 +。
如果您要处理的旧代码库需要旧的行为,但您的平台是新的Ubuntu,请从PyPI安装MySQLdb:
$ pip install MySQL-python==1.2.3
答案 6 :(得分:0)
我在执行时遇到此错误
SELECT * FROM table;
我将错误跟踪到cursor.py第195行。
if args is not None:
if isinstance(args, dict):
nargs = {}
for key, item in args.items():
if isinstance(key, unicode):
key = key.encode(db.encoding)
nargs[key] = db.literal(item)
args = nargs
else:
args = tuple(map(db.literal, args))
try:
query = query % args
except TypeError as m:
raise ProgrammingError(str(m))
鉴于我要输入任何其他参数,所以我摆脱了所有“ if args ...”分支。现在可以了。