1

我有一个在循环中运行的查询字符串,并且列表查询中的每个项目都被执行。该列表包含字符串,我使用 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"\'")

但这也不起作用。我还看到这个问题的答案是使用我不知道的 mysqldb 库内置功能,所以我寻求 stackoverflow 社区的帮助来解决这个问题。

我更改了代码以反映答案中建议的解决方案,但结果是相同的:这是更改:

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'>
4

3 回答 3

4

如果您dbCursor.execute使用两个参数调用,您的数据库适配器将为您引用参数。有关详细信息,请参阅DB-API 规范

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)

%sinquery是参数标记。它将被 中给出的带引号的参数替换args。要使用的正确参数标记取决于您的数据库适配器。例如MySQLdb使用%s,而oursqlsqlite3使用?.

推荐使用参数化 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')a也是如此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)

我不确定为什么 DB 适配器会latin-1在您想要的时候尝试对 unicode 进行编码utf-8。最好的解决方案是追踪这种选择的latin-1来源。

一个 hacky 解决方法是尝试自己对字符串进行编码:

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)

但让我强调一下,我真的不认为这是最好的方法,也不应该这样做。

于 2013-04-27T15:43:24.457 回答
0

我在这里添加了一个类似问题的答案,你也可以看看它!

链接:https ://stackoverflow.com/a/61042304/8939258

于 2020-04-05T12:09:00.967 回答
0

我放弃逃避它。相反,我将单引号替换为通配符%

text = "woman's"
text = text.replace("'","%")

它在mysql中完美运行

于 2020-04-30T15:19:17.290 回答