2017-09-30 1 views
0

Lesen Wenn ich versuche zu laufen:Django Codierungsfehler, wenn aus einer CSV-

import csv 

with open('data.csv', 'rU') as csvfile: 
    reader = csv.DictReader(csvfile) 
    for row in reader: 
    pgd = Player.objects.get_or_create(
     player_name=row['Player'], 
     team=row['Team'], 
     position=row['Position'] 
    ) 

Die meisten meiner Daten wird in der Datenbank erstellt, mit Ausnahme einer bestimmten Zeile. Wenn mein Skript die Zeile erreicht, erhalte ich die Fehlermeldung:

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.` 

Die bestimmte Zeile in der CSV, die diesen Fehler verursacht, ist:

>>> row 
{'FR\xed\x8aD\xed\x8aRIC.ST-DENIS', 'BOS', 'G'} 

Ich habe mit dem an den anderen ähnlichen Themen sieht Stackoverflow gleiche oder ähnliche Probleme, aber die meisten sind nicht spezifisch für die Verwendung von Sqlite mit Django. Irgendein Rat?

Wenn es wichtig ist, führe ich das Skript aus, indem ich in die Django-Shell gehe, indem ich python manage.py shell aufruft, und kopiere es in, anstatt nur das Skript von der Befehlszeile aus aufzurufen.

Dies ist der Stacktrace ich:

Traceback (most recent call last): 
    File "<console>", line 4, in <module> 
    File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/csv.py", line 108, in next 
    row = self.reader.next() 
    File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/codecs.py", line 302, in decode 
    (result, consumed) = self._buffer_decode(data, self.errors, final) 
UnicodeDecodeError: 'utf8' codec can't decode byte 0xcc in position 1674: invalid continuation byte 

EDIT: habe ich beschlossen, diesen Eintrag in der Datenbank nur manuell zu importieren, anstatt zu versuchen, es aus meiner CSV zu lesen, auf Basis von Alastair McCormack Feedback

Based on the output from your question, it looks like the person who made the CSV mojibaked it - it doesn't seem to represent FRÉDÉRIC.ST-DENIS. You can try using windows-1252 instead of utf-8 but I think you'll end up with FRíŠDíŠRIC.ST-DENIS in your database.

+0

Python 2. x oder 3.x? –

+0

Python 2.x, aber das ist ein neues Projekt. Wenn ich also auf 3.x umsteigen kann, werde ich es einfacher machen. – Konrad

Antwort

0

Encode Spielername in utf-8 .encode('utf-8') in Spielernamen import csv

mit
with open('data.csv', 'rU') as csvfile: 
    reader = csv.DictReader(csvfile) 
    for row in reader: 
    pgd = Player.objects.get_or_create(
     player_name=row['Player'].encode('utf-8'), 
     team=row['Team'], 
     position=row['Position'] 
    ) 
+0

Wenn ich encode hinzugefügt habe, bekomme ich den Fehler: 'UnicodeDecodeError: 'ascii' Codec kann Byte 0xcc in Position 2 nicht dekodieren: Ordinal nicht im Bereich (128) .' – Konrad

+0

Das liegt daran, dass die Datei bereits 8bit codiert ist. '.encode() 'macht hier keinen Sinn –

1

Ich vermute, Sie verwenden Python 2 - open() gibt Str zurück, die einfach Bytefolgen sind.

Der Fehler sagt Ihnen, dass Sie Ihren Text in Unicode-Zeichenkette vor der Verwendung zu decodieren müssen.

Die einfachste Methode besteht darin, jede Zelle zu entschlüsseln:

with open('data.csv', 'r') as csvfile: # 'U' means Universal line mode and is not necessary 
    reader = csv.DictReader(csvfile) 
    for row in reader: 
    pgd = Player.objects.get_or_create(
     player_name=row['Player'].decode('utf-8), 
     team=row['Team'].decode('utf-8), 
     position=row['Position'].decode('utf-8) 
    ) 

Das wird funktionieren, aber es ist hässlich Add decodiert überall, und es wird durch das Öffnen von Dateien im Textmodus nicht funktioniert Dinge in Python 3. Python 3 verbessert und Rückgabe von Python 3 Strings, die den Unicode Strings in Py2 entsprechen.

Um dieselbe Funktionalität in Python 2 zu erhalten, verwenden Sie das Modul io. Dies gibt Ihnen eine open() Methode, die eine encoding Option hat. Dummerweise wird das Python 2.x CSV-Modul mit Unicode gebrochen, so benötigen Sie eine zurückportierte Version zu installieren:

pip install backports.csv 

Um Ihren Code und zukunftssicher es ordentlich, tun:

import io 
from backports import csv 

with io.open('data.csv', 'r', encoding='utf-8') as csvfile: 
    reader = csv.DictReader(csvfile) 
    for row in reader: 
    # now every row is automatically decoded from UTF-8 
    pgd = Player.objects.get_or_create(
     player_name=row['Player'], 
     team=row['Team'], 
     position=row['Position'] 
    ) 
+0

Wenn ich die Dekodierung hinzugefügt habe, bekomme ich diesen Fehler:' UnicodeDecodeError: 'utf8' Codec kann Byte 0xcc in Position 2: ungültiges Fortsetzungsbyte nicht dekodieren. Ich werde deine Backport-Idee ausprobieren. – Konrad

+0

Die Verwendung von Backports funktionierte auch nicht. Es gab mir den Fehler "UnicodeDecodeError: 'utf8' Codec kann Byte 0xcc in Position 1674 nicht dekodieren: ungültiges Fortsetzungsbyte" auf dem gleichen lästigen Datensatz. Ich musste auch 'from io import open' verwenden. – Konrad

+0

Ah, ich nahm an, dass die CSV UTF-8 kodiert war. Welche Codierung ist die CSV? –