我有一个在循环中运行的查询字符串,对于列表查询中的每个项目都会执行。该列表包含字符串,我使用 python 字符串格式技术将查询替换为列表中的相应字符串作为迭代进度。
我已经对查询和列表中的字符串进行了统一编码:这是我的统一编码查询:
query = ur'''SELECT something FROM some_table WHERE some_name LIKE "{this_name}%"'''
在执行之前,我将查询字符串编码为 utf-8
try:
formatted_query = query.format(this_name=list_name)
#encode the query
encoded_q = formatted_query.encode('utf-8')
# execute the query
self.dbCursor.execute(encoded_q)
row = self.dbCursor.fetchone()
except Exception, e:
traceback.print_exc()
但问题是有时我会遇到列表中的字符串,该列表中有单引号示例:foo's
。我已经使用 utf-8 进行了 unicode 编码,我认为这样做我不必担心这种情况。但是我收到 sql 错误,因为 MySQL 没有跳过单引号。
我的下一次尝试是替换单引号:
format_string = u"foo's".replace(u"'",u"\'")
但这也不起作用。我还看到了 this question 的答案正在使用我不知道的 mysqldb 库内置功能,因此我寻求 stackoverflow 社区的帮助来解决这个问题。
我更改了代码以反射(reflect)答案中建议的解决方案,但结果是一样的:更改如下:
args = [u"{this_name}%".format(this_name=format_name)]
self.dbCursor.execute(query.encode('utf-8'), args)
#error 在这一行被抛出:
错误:
UnicodeEncodeError: 'latin-1' codec can't encode character u'\u014d' in position 4: ordinal not in range(256)
这是错误提示的字符串,我已经检查了该字符串的类型,它是一个统一编码的字符串。
this_name= Sentōkisei type= <type 'unicode'>
最佳答案
如果您使用两个参数调用 dbCursor.execute
,您的数据库适配器将为您引用这些参数。查看DB-API specification详情:
query = u'''SELECT something FROM some_table WHERE some_name LIKE %s'''
args = [u"{this_name}%".format(this_name=list_name)]
self.dbCursor.execute(query, args)
query
中的 %s
是 parameter marker .它将被 args
中给出的带引号的参数替换。要使用的正确参数标记取决于您的数据库适配器。例如,MySQLdb使用 %s
,而 oursql和 sqlite3使用 ?
。
使用参数化 SQL 是推荐的方式。你真的不应该自己引用这些论点。
关于错误,你发帖
this_name= Sentōkisei type= <type 'unicode'>
我假设这意味着 format_name
是 unicode。因此,
args = [u"{this_name}%".format(this_name=format_name)]
将使 args
成为包含一个 unicode 的列表。
现在我们到达引发错误的行:
self.dbCursor.execute(query.encode('utf-8'), args)
query
已经是 unicode
。如果您对该 unicode 进行编码,那么它会变成一个 str
。所以query.encode('utf-8')
是一个str
,但是args
是一个unicode
的列表.我不确定您为什么要对 query
进行编码,但是您的数据库适配器应该能够接受两个 unicode 参数。所以试试
self.dbCursor.execute(query, args)
现在,在重新阅读您的评论后,您似乎已经尝试过了,但它也引发了同样的错误:
UnicodeEncodeError: 'latin-1' codec can't encode character u'\u014d' in position 75: ordinal not in range(256)
我不确定为什么当您需要 utf-8
时,DB 适配器会尝试使用 latin-1
对 unicode 进行编码。最好的解决方案是追踪这个 latin-1
的选择是从哪里来的。
一个棘手的解决方法是尝试自己对字符串进行编码:
query = u'''SELECT something FROM some_table WHERE some_name LIKE %s'''.encode('utf-8')
args = [u"{this_name}%".format(this_name=list_name).encode('utf-8')]
self.dbCursor.execute(query, args)
但我要强调,我真的不认为这是最好的方法,也没有必要。
关于Python:从 MySQL 查询中转义单引号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16253746/