如何在Google App Engine数据存储中存储非ASCII字符

3

我已经尝试了不少于5种不同的“解决方案”,但都无法使其正常工作,请帮助。

以下是错误信息:

  'ascii' codec can't decode byte 0xc3 in position 1: ordinal not in range(128)
  Traceback (most recent call last):
  File "/base/python_runtime/python_lib/versions/1/google/appengine/ext/webapp/__init__.py", line 636, in __call__
    handler.post(*groups)
  File "/base/data/home/apps/elmovieplace/1.350096827241428223/script/pftv.py", line 114, in post
    movie.put()
  File "/base/python_runtime/python_lib/versions/1/google/appengine/ext/db/__init__.py", line 984, in put
    return datastore.Put(self._entity, config=config)
  File "/base/python_runtime/python_lib/versions/1/google/appengine/api/datastore.py", line 455, in Put
    return _GetConnection().async_put(config, entities, extra_hook).get_result()
  File "/base/python_runtime/python_lib/versions/1/google/appengine/datastore/datastore_rpc.py", line 1219, in async_put
    for pbs in pbsgen:
  File "/base/python_runtime/python_lib/versions/1/google/appengine/datastore/datastore_rpc.py", line 1070, in __generate_pb_lists
    pb = value_to_pb(value)
  File "/base/python_runtime/python_lib/versions/1/google/appengine/api/datastore.py", line 239, in entity_to_pb
    return entity._ToPb()
  File "/base/python_runtime/python_lib/versions/1/google/appengine/api/datastore.py", line 841, in _ToPb
    properties = datastore_types.ToPropertyPb(name, values)
  File "/base/python_runtime/python_lib/versions/1/google/appengine/api/datastore_types.py", line 1672, in ToPropertyPb
    pbvalue = pack_prop(name, v, pb.mutable_value())
  File "/base/python_runtime/python_lib/versions/1/google/appengine/api/datastore_types.py", line 1485, in PackString
    pbvalue.set_stringvalue(unicode(value).encode('utf-8'))
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 1: ordinal not in range(128)

这是导致我遇到问题的代码部分。
if imdbValues[5] == 'N/A':
    movie.diector = ''
else:
    movie.director = imdbValues[5]

...

movie.put()

在这种情况下,imdbValues[5]等于Claudio Fäh

2
你应该阅读这篇文章:http://blog.notdot.net/2010/07/Getting-unicode-right-in-Python。你需要确保清楚地知道何时处理字节,何时处理字符串以及在转换两者之间时应使用哪种编码。像你看到的编码/解码错误通常是由于对字符串处理的误解而导致的。 - Nick Johnson
2个回答

4
这个异常由下面这行代码引发:
pbvalue.set_stringvalue(unicode(value).encode('utf-8'))

当你将一个值传递给movie.director时,该值首先会被转换为Unicode格式。
unicode(value)

然后使用encode('utf-8')进行编码。

unicode()函数通常使用ASCII作为默认解码编码;这意味着您只能安全地传递这些类型的值:

  1. Unicode字符串
  2. 8位字符串

您的代码可能会传递一个字节字符串,该字符串使用unicode(value)无法在ASCII中解码。

建议:
如果您正在处理字节字符串,则必须知道它们的编码,否则您的程序将遇到这种编码/解码问题。

如何解决:
发现您正在处理的字节字符串中使用的编码(utf-8?),并将它们转换为Unicode字符串。
例如,如果imdbValues是由一些花哨的Imdb python库返回的包含utf-8编码字节字符串的列表,则应使用以下方法进行转换:

 movie.director = imdbValues[5].decode('utf-8')

另外,如果您不介意回答另一个问题,是否有一种方法可以使用列表来完成这个任务。 - user684970
@Jon 尝试使用列表推导式:unicode_list = [item.decode('utf-8') for item in imdbValues] - systempuntoout
我想要做同样的事情。我有一个名为“全部”的应用引擎任务。该字符串以utf-8编码。尝试使用decode(utf-8)解码,但仍然遇到相同的错误:“'ascii' codec can't decode byte”。 - sohil

2
你应该开始使用unicode处理文本数据。
不管你从哪里获取数据,它们都是Unicode字符编码的字节。编码可以是UTF-8UTF-16Windows-1252ISO-8859-1或许多其他编码方式。如果数据存在于你的系统中,你会知道它们的编码方式。如果它们来自网页,则编码方式包含在响应头中,通常位于页面开头。使用该编码方式,使用.decode方法将其转换为非常有用的unicode Python对象,并在你的代码中使用它。
输入时进行解码,在输出时进行编码(如果必要)。在使用 App Engine 中的数据时,不需要先进行编码。
附注:这个与Unicode相关的问题的答案可能会对你有所帮助。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接