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

3 投票
2 回答
2959 浏览
提问于 2025-04-16 16:44

我试过不少于五种不同的“解决方案”,但就是没法搞定,请帮帮我。

这是我遇到的错误

  '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 个回答

2

你应该开始使用 unicode 来处理你的文本数据。

无论你从哪里获取数据,这些数据都是以字节形式编码的 Unicode 字符。编码方式可能是 UTF-8UTF-16Windows-1252ISO-8859-1 或其他很多编码。如果数据存储在你的系统上,你就知道它的编码方式。如果数据来自网页,编码信息通常会包含在响应头中,或者在页面的开头部分。使用这个编码,通过 .decode 转换成非常有用的 unicode Python 对象,然后在你的代码中使用它。

在输入时进行解码,输出时(如果需要的话)进行编码。在使用数据时,不必在 App Engine 上提前编码。

PS 这个关于 Unicode 的问题的回答可能会对你有帮助。

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

撰写回答