如何在Google App Engine Datastore中存储非ASCII字符
我试过不少于五种不同的“解决方案”,但就是没法搞定,请帮帮我。
这是我遇到的错误
'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 个回答
你应该开始使用 unicode
来处理你的文本数据。
无论你从哪里获取数据,这些数据都是以字节形式编码的 Unicode 字符。编码方式可能是 UTF-8
、UTF-16
、Windows-1252
、ISO-8859-1
或其他很多编码。如果数据存储在你的系统上,你就知道它的编码方式。如果数据来自网页,编码信息通常会包含在响应头中,或者在页面的开头部分。使用这个编码,通过 .decode
转换成非常有用的 unicode
Python 对象,然后在你的代码中使用它。
在输入时进行解码,输出时(如果需要的话)进行编码。在使用数据时,不必在 App Engine 上提前编码。
PS 这个关于 Unicode 的问题的回答可能会对你有帮助。
这个错误是由以下这行代码引起的:
pbvalue.set_stringvalue(unicode(value).encode('utf-8'))
当你给 movie.director
传一个值时,这个值会先被转换成unicode格式,具体是通过:
unicode(value)
然后再用 encode('utf-8')
进行编码。
unicode()
函数通常默认使用ASCII作为解码方式;这意味着你只能安全地传入以下两种类型的值:
- 一个unicode字符串
- 一个8位字符串
你的代码可能传入了一个字节字符串,但这个字符串的编码方式让 unicode(value)
在用ASCII解码时失败了。
建议:
如果你在处理字节字符串,你必须知道它们的编码方式,否则你的程序会遇到这种编码/解码的问题。
如何解决:
找出你正在处理的字节字符串的编码方式(比如utf-8?),然后把它们转换成unicode字符串。
例如,如果 imdbValues
是某个高级 Imdb python库 返回的包含utf-8编码字节字符串的列表,你应该使用以下方法进行转换:
movie.director = imdbValues[5].decode('utf-8')