2012-04-23 39 views
66

I tiene un problema con la codificación de la trayectoria variable y de insertarlo a la base de datos SQLite. Traté de resolverlo con la función encode ("utf-8") que no ayudó. Luego usé unicode() función que me da el tipo unicode.Uso de Unicode() y encode() funciones en Python

print type(path)     # <type 'unicode'> 
path = path.replace("one", "two") # <type 'str'> 
path = path.encode("utf-8")  # <type 'str'> strange 
path = unicode(path)    # <type 'unicode'> 

Finalmente he ganado Unicode tipo, pero todavía tengo el mismo error que estaba presente cuando el tipo de la variables camino era str

sqlite3.ProgrammingError: You must not use 8-bit bytestrings unless you use a text_factory that can interpret 8-bit bytestrings (like text_factory = str). It is highly recommended that you instead just switch your application to Unicode strings.

Podría ayudar a resolver este error y explicar el uso correcto de las funciones encode("utf-8") y unicode()? A menudo peleo con eso.

EDIT:

Este ejecutar() declaración elevó el error:

cur.execute("update docs set path = :fullFilePath where path = :path", locals()) 

me olvidó cambiar la codificación de fullFilePath variable que sufre el mismo problema, pero estoy bastante confundido ahora. ¿Debo usar solo unicode() o codificar ("utf-8") o ambos?

no puedo usar

fullFilePath = unicode(fullFilePath.encode("utf-8")) 

porque plantea este error:

UnicodeDecodeError: 'ascii' codec can't decode byte 0xc5 in position 32: ordinal not in range(128)

Python versión es 2.7.2

+0

¿dónde está el código que provoca el error? – newtover

+2

Su pregunta exacta ya ha sido respondida: [http://stackoverflow.com/questions/2392732/sqlite-python-unicode-and-non-utf-data][1] [1]: http: // stackoverflow.com/questions/2392732/sqlite-python-unicode-and-non-utf-data – garnertb

+0

@newtover He editado la pregunta. – xralf

Respuesta

73

está usando el encode("utf-8") incorrectamente. Las cadenas de bytes de Python (tipo str) tienen una codificación, Unicode no. Puede convertir una cadena Unicode en una cadena de bytes de Python usando uni.encode(encoding), y puede convertir una cadena de bytes en una cadena Unicode usando s.decode(encoding) (o equivalentemente, unicode(s, encoding)).

Si fullFilePath y path Actualmente un tipo str, se debe encontrar la forma en que se codifican.Por ejemplo, si la codificación actual es UTF-8, se debería utilizar:

path = path.decode('utf-8') 
fullFilePath = fullFilePath.decode('utf-8') 

Si esto no lo arregla, el problema real puede ser que usted no está utilizando una cadena Unicode en su llamada execute(), intenta cambiándolo a lo siguiente:

cur.execute(u"update docs set path = :fullFilePath where path = :path", locals()) 
+0

Esta declaración 'fullFilePath = fullFilePath.decode (" utf-8 ")' aún provoca error 'UnicodeEncodeError: 'ascii' codec no puede codificar caracteres en la posición 32-34: ordinal no en rango (128)' . fullFilePath es una combinación de tipo * str * y cadena tomada de la columna * text * de la tabla db que debe ser codificación utf-8. – xralf

+0

De acuerdo con [este] (http://www.sqlite.org/datatype3.html) pero puede ser UTF-8, UTF-16BE o UTF-16LE. ¿Puedo descubrirlo de alguna manera? – xralf

+0

@xralf, si está combinando diferentes objetos 'str', puede que esté mezclando codificaciones. ¿Puedes mostrar el resultado de 'print repr (fullFilePath)'? –

97

str es una representación de texto en bytes, unicode es una representación de texto en caracteres.

Decodifica texto de bytes a unicode y codifica un unicode en bytes con alguna codificación.

Eso es:

>>> 'abc'.decode('utf-8') # str to unicode 
u'abc' 
>>> u'abc'.encode('utf-8') # unicode to str 
'abc' 
+2

Gracias. información muy útil. – Rupam

+0

Respuesta muy clara, muy inteligente gracias –

+0

Muy buena respuesta, directamente al grano. Añadiría que 'unicode' habla sobre letras o símbolos, o más genéricamente: ** runes **, mientras que' str' representa una cadena de bytes en una determinada codificación, que debe 'decode' (obviamente en la codificación correcta) para obtener las runas específicas – arainone

1

Asegúrese de que haya configurado los valores de localización justo antes de ejecutar la secuencia de comandos de la shell, por ejemplo,

$ locale -a | grep "^en_.\+UTF-8" 
en_GB.UTF-8 
en_US.UTF-8 
$ export LC_ALL=en_GB.UTF-8 
$ export LANG=en_GB.UTF-8 

Docs: man locale, man setlocale.

Cuestiones relacionadas