1

我有这样的功能:

def convert_to_unicode(data):
    row = {}
    if data == None:
        return data
    try:
        for key, val in data.items():
            if isinstance(val, str):
                row[key] = unicode(val.decode('utf8'))
            else:
                row[key] = val
        return row
    except Exception, ex:
        log.debug(ex)

MySQLdb.cursors.DictCursor逐行提供一个结果集(使用)以将所有字符串值转换为 unicode(示例{'column_1':'XXX'}变为{'column_1':u'XXX'})。

问题是其中一行具有类似的值{'column_1':'Gabriel García Márquez'} 并且它没有被转换。它抛出这个错误:

'utf8' codec can't decode byte 0xed in position 12: invalid continuation byte

当我搜索这个时,这似乎与 ascii 编码有关。

我尝试的解决方案是:

  1. 在我的文件开头添加# -*- coding: utf-8 -*-......没有帮助

  2. 按预期将行更改row[key] = unicode(val.decode('utf8'))row[key] = unicode(val.decode('utf8', 'ignore'))... 它会忽略非 ascii 字符并返回{'column_1':u'Gabriel Garca Mrquez'}

  3. 将行更改row[key] = unicode(val.decode('utf8'))row[key] = unicode(val.decode('latin-1'))...可以完成工作,但恐怕它将仅支持西欧字符(根据此处

谁能指出我正确的方向。

4

2 回答 2

3

首先:

  • 您在结果集中获得的数据已明确latin-1编码,否则您不会观察到这种行为。尝试解码 - 编码的字节字符串就像它是- 编码的一样在你的脸上炸毁是完全正确的。一旦你有一个-encoded byte string ,如果你想将它转换为 unicode 类型,是正确的做法。latin-1utf-8latin-1foofoo.decode('latin1')

  • 我注意到unicode(val.decode('utf8'))您代码中的表达式。这等同于val.decode('utf8'); 调用.decode字节字符串的方法会将其转换为 unicode,因此您调用unicode()的是 unicode 字符串,它只返回 unicode 字符串。

第二:

  • 你真正的问题 - 如果你希望能够处理不包含在编码支持的字符集中的字符latin-1- 不是 Python 的字符串类型本身,而是 MySQLdb 库。我不详细了解这个问题,但据我了解,在 MySQL 的古代版本中,MySQL 数据库使用的默认编码是latin-1,但现在是utf-8(并且已经很多年了)。然而,MySQLdb 库仍然默认建立latin-1与数据库的编码连接。确实有几十个与 MySQL、Python 和字符串编码相关的 StackOverflow 问题,虽然我并不完全理解它们,但似乎对人们有用的所有此类问题的一种易于使用的解决方案是: http://www.dasprids.de/blog/2007/12/17/python-mysqldb-and-utf-8

我希望我能给你一个关于 MySQLdb 问题的更全面和自信的答案,但我什至从未使用过 MySQL,我不想冒险发布任何不真实的东西。也许有人可以过来提供更多细节。尽管如此,我希望这对您有所帮助。

于 2012-12-15T10:31:41.160 回答
2

您的第三个解决方案 - 将编码更改为"latin-1"- 是正确的。您的输入数据被编码为 Latin-1,因此您必须将其解码为。除非某个地方的某个人做了一些非常愚蠢的事情,否则该输入数据应该不可能包含该编码的无效字符。

于 2012-12-15T08:32:45.123 回答