2010-03-24 12 views
7

Ich habe eine Datenbank in MSSQL, die ich nach SQLite/Django portiere. Ich verwende pymssql, um eine Verbindung zur Datenbank herzustellen und ein Textfeld in der lokalen SQLite-Datenbank zu speichern.Konvertieren oder Entfernen von "illegalen" Unicode-Zeichen

Jedoch für einige Zeichen explodiert es. Ich bekomme Beschwerden wie folgt:

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

Gibt es eine Möglichkeit, die Zeichen in richtige Unicode-Versionen konvertieren? Oder sie ausziehen?

Antwort

11

sind Sobald Sie die Bytefolge s, anstatt sie direkt als Unicode-Obj zu verwenden, wandle sie explizit mit dem richtigen Codec um, zB:

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

und u statt s im Code verwenden, die diesen Punkt folgt (vermutlich der Teil, der auf SQLite schreibt). Das geht davon aus, latin-1 ist die Codierung, die verwendet wurde, um die Byte-Zeichenfolge ursprünglich zu machen - es ist unmöglich für uns zu erraten, also versuchen Sie es herauszufinden ;-).

Als allgemeine Regel schlage ich vor: Verarbeiten Sie in Ihren Anwendungen keinen Text als codierte Byte-Strings - dekodieren Sie sie direkt nach der Eingabe in Unicode-Objekte und codieren sie, falls notwendig, vor der Ausgabe wieder in Byte-Strings .

+5

In der Tat müssen Sie wissen, in welcher Kodierung Ihr Text ist. Es gibt so ziemlich keinen Weg. In Ihrem Fall macht Ihre Fehlermeldung glücklicherweise deutlich. Es ist fast sicher, dass Sie mit Microsofts nervigem cp1252 zu tun haben, da ein 0x97-Zeichen vorhanden ist. In latin-1 enthält dieser Codepunkt das Kontrollzeichen "ENDE DER GEWACHTEN FLÄCHE", das fast nie verwendet wird. Sie werden diesen genauen Fehler mit utf-8 nie sehen, da 0x97 kein gültiges zeichenführendes Byte ist. In cp1252 ist es andererseits die sehr häufige. – jcdyer

11

Wenn Sie entschlüsseln, nur 'ignorieren' passieren diese Zeichen

es abzustreifen einige weitere Möglichkeit der Stripping/Umwandlung diejenigen

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

-Test

>>> "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 löst Fehler aus, auch wenn 'ignore' verwendet wird. Es scheint keine Kombination von Dekodierung/Kodierung zu geben, mit der ich alle nutzlosen UTF-8-Zeichen aussortieren kann, die ich nicht im geringsten erwähnen konnte. – user1244215

Verwandte Themen