2011-05-01 4 views
3

J'ai essayé pas moins de 5 "solutions" différentes et je ne peux pas le faire fonctionner, s'il vous plaît aider.Comment stockez-vous un caractère non-ASCII dans le magasin de données Google App Engine

C'est l'erreur

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

Ceci est la partie du code qui me donne des problèmes.

if imdbValues[5] == 'N/A': 
    movie.diector = '' 
else: 
    movie.director = imdbValues[5] 

... 

movie.put() 

Dans ce cas imdbValues[5] est égal à Claudio Fäh

+2

Vous devriez lire ceci: http: // blog.notdot.net/2010/07/Getting-unicode-right-in-Python. Vous devez vous assurer que vous êtes clair sur quand vous avez affaire à des octets, quand vous traitez des chaînes, et quel encodage vous devriez utiliser pour convertir entre les deux. Les erreurs d'encodage/décodage telles que vous les voyez se produisent généralement à cause de malentendus sur la gestion des chaînes. –

Répondre

5

L'exception est soulevée par cette ligne de code:

pbvalue.set_stringvalue(unicode(value).encode('utf-8')) 

Lorsque vous passez une valeur à movie.director, cette valeur est d'abord converti en unicode avec:

unicode(value) 

alors il est codé avec encode('utf-8').

La fonction unicode() utilise typiquement ASCII comme codage de décodage par défaut; cela signifie que vous êtes en sécurité que passer ce genre de valeurs:

  1. Chaîne unicode
  2. Une chaîne 8 bits

Votre code est probablement passer une chaîne d'octets avec un codage que le unicode(value) échoue décoder en ASCII.

Recommandation:
si vous faites affaire avec des chaînes d'octets, vous devez connaître leur encodage ou votre programme souffriront ce genre de problème de codage/décodage.

Résolution du problème:
découvrir l'encodage utilisé dans les chaînes d'octets que vous traitez (utf-8?) Et de les convertir en chaînes unicode.
Si, par exemple, imdbValues est une liste renvoyée par certaines bibliothèques python fantaisie Imdb qui contient des chaînes d'octets UTF-8, vous devez les convertir à l'aide:

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

merci, a parfaitement fonctionné. –

+0

aussi si cela ne vous dérange pas de répondre à une autre question, y at-il un moyen de le faire avec des listes. –

+0

@Jon essayer avec une liste de compréhension: 'unicode_list = [item.decode ('utf-8') pour l'élément dans imdbValues]' – systempuntoout

2

Vous devriez commencer à utiliser unicode pour vos données textuelles. Où que vous receviez vos données, ce sont des caractères Unicode codés en octets. Le codage pourrait être UTF-8, ou UTF-16, ou Windows-1252, ou ISO-8859-1 ou bien d'autres codages. Si les données existent sur votre système, vous connaissez l'encodage. Si elles proviennent d'une page Web, l'encodage est inclus dans les en-têtes de réponse, et souvent au début de la page. En utilisant ce codage, .decode à l'objet Python unicode très utile et l'utiliser dans votre code.

Décoder en entrée, encoder (si nécessaire) en sortie. Il n'est pas nécessaire de coder avant d'utiliser les données avec App Engine.

PS that répondre dans une question liée à Unicode pourrait être utile.

Questions connexes