2010-03-24 35 views
7

Tengo una base de datos en MSSQL que estoy migrando a SQLite/Django. Estoy usando pymssql para conectarme a la base de datos y guardar un campo de texto en la base de datos SQLite local.Convertir o eliminar caracteres Unicode "ilegales"

Sin embargo, para algunos personajes explota. Recibo quejas de esta manera:

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

¿Hay alguna manera de que pueda convertir los caracteres Unicode a las versiones correctas? ¿O quitárselos?

Respuesta

11

Una vez que tenga la cadena de bytes s, en lugar de usarlo como obj unicode directamente, conviértalo explícitamente con el códec correcto, p. ej .:

u = s.decode('latin-1') 

y utilizar u en lugar de s en el código que sigue a este punto (presumiblemente la parte que escribe en SQLite). Eso es suponiendo que latin-1 es la codificación que se usó originalmente para crear la cadena de bytes, es imposible para nosotros adivinar, así que trate de averiguar ;-).

Como regla general, sugiero: no procese en sus aplicaciones ningún texto como cadenas de bytes codificadas: decodifíquelas a objetos Unicode inmediatamente después de la entrada y, si es necesario, codifíquelas nuevamente en cadenas de bytes justo antes de la salida .

+5

De hecho, debes saber en qué codificación está el texto. No hay forma de evitar esto. En su caso, afortunadamente, su mensaje de error lo hace obvio. Es casi seguro apostar que estás lidiando con la molesta cp1252 de Microsoft, debido a la presencia de un personaje de 0x97. En latin-1, este punto de código tiene un carácter de control, "FIN DEL ÁREA PROTEGIDA", que casi nunca se usa. Nunca verá este error preciso con utf-8, ya que 0x97 no es un byte líder en caracteres válido. En cp1252, por otro lado, es el emdash muy común. – jcdyer

11

Al decodificar, sólo tiene que pasar 'ignorar' para despojar a esos personajes

hay alguna manera más de despojar/convertir esas son

'replace': replace malformed data with a suitable replacement marker, such as '?' or '\ufffd' 

'ignore': ignore malformed data and continue without further notice 

'backslashreplace': replace with backslashed escape sequences (for encoding only) 

prueba

>>> "abcd\x97".decode("ascii") 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
UnicodeDecodeError: 'ascii' codec can't decode byte 0x97 in position 4: ordinal not in range(128) 
>>> 
>>> "abcd\x97".decode("ascii","ignore") 
u'abcd' 
+12

python arroja errores incluso cuando se usa 'ignorar'. Parece que no hay una combinación de decodificación/codificación que pueda quitar cualquier carácter UTF-8 inútil que no pueda dar la más mínima mierda. – user1244215

Cuestiones relacionadas