2013-03-19 13 views
16

so in Ordnung, wie der Titel schlägt das Problem, das ich habe mit Eingabe aus einer Windows-1252-codierten Datei in Python und Einfügen dieser Eingabe in SQLAlchemy-MySql Tabelle korrekt lesen .Korrekt Lesen von Text aus Windows-1252 (cp1252) Datei in Python

Die aktuelle Systemkonfiguration:
Windows 7 VM mit "Roger Access Control System", die die Datei ausgibt;
Ubuntu 12.04 LTS VM mit einem freigegebenen Ordner auf dem Windows-System, so dass ich mit "Python 2.7.3" auf die Datei zugreifen kann.

Jetzt zum eigentlichen Problem, für die Eingabedatei habe ich einen "VM shared-Ordner", der eine Datei enthält, die auf einem Windows 7-System durch Roger Access Control System (roger.pl für weitere Details) generiere Datei wird "PREvents.csv" genannt, die zu ihrem Inhalt ein ";" vorschlägt; getrennte Liste von Daten.

Ein beispielhaftes Format der Daten:

2013-03-19;15:58:30;100;Jānis;Dumburs;1;Uznemums1;0;Ieeja; 
2013-03-19;15:58:40;100;Jānis;Dumburs;1;Uznemums1;2;Izeja; 

Das vierte Feld enthält die Karteninhabernamen und 5. enthält der Besitzer Nachnamen, enthält die sechsten die zugewiesene Gruppenbesitzer.

Das Problem kommt von der Tatsache, dass einer der drei oben genannten Bereichen spezifischen Zeichen lettische Sprache enthalten kann, in dem Beispiel das Wort „Janis“ enthält den Buchstaben „A“, die in Unicode 257.

ist Datei

als ich gewohnt bin, öffne ich die Datei als solche:

try: 
    f = codecs.open(file, 'rb', 'cp1252') 
except IOError: 
    f = codecs.open(file, 'wb', 'cp1252') 

Bisher funktioniert alles - es die Datei öffnet und ich bewege mich so auf über jede Zeile der Datei zu wiederholen (dies ist ein Continuos running script so entschuldigen Sie die Schleife):

while True: 
    line = f.readline() 

    if not line: 
     # Pause loop for 1 second 
     time.sleep(1) 
    else: 
     # Split the line into list 
     date, timed, userid, firstname, lastname, groupid, groupname, typed, pointname, empty = line.split(';') 

Und das ist, wo die Probleme beginnen, wenn ich print repr(firstname) es druckt u'J\xe2nis' die, soweit ich finde, nicht korrekt ist - `\ xe2 \ nicht das lettische Zeichen" A "darstellt.
weiter unten in der Schleife je nach Ereignistyp zuordnen ich die Variablen SQLAlchemy Objekt und insert/update:

if typed == '0': # Entry type 
    event = Events(
     period, 
     fullname, 
     userid, 
     groupname, 
     timestamp, 
     0, 
     0 
    ) 
    session.add(event) 
else: # Exit type 
    event = session.query(Events).filter(
     Events.period == period, 
     Events.exit == 0, 
     Events.userid == userid 
    ).first() 
    if event is not None: 
     event.exit = timestamp 
     event.spent = timestamp - event.entry 

# Commit changes to database 
session.commit() 

Auf der Suche nach Antworten, die ich gefunden habe, wie die Standardcodierung definieren zu verwenden:

import sys 
reload(sys) 
sys.setdefaultencoding('utf-8') 

Das hat mir in keiner Weise geholfen.

Im Grunde ist das alles führt zu der mich nicht in der Lage, die richtigen Besitzer Vor-/Nachname aswell einfügen als Eigentümer Gruppenname zugeordnet, wenn sie eines lettischen spezifische Zeichen enthalten, zB:

Instead of the character "ā" it inserts "â" 

Ich möchte auch hinzufügen, dass ich die Dateiverschlüsselung "PREvents.csv" nicht ändern kann und das "RACS" -System das Einfügen in UTF-8- oder Unicode-Dateien nicht unterstützt - wenn Sie so oder so versuchen, fügt das System Zufallssymbole für die Lettisch-spezifische Charaktere.

Bitte lassen Sie mich jetzt, wenn andere Informationen benötigt wird, ich es gerne liefern werde :)

Jede Hilfe sehr geschätzt würde.

+0

Das lettische Zeichen ist in CP1252 überhaupt nicht verfügbar. Sie können keine CP1252-codierte Datei erstellen, die dieses Zeichen enthält. (Haben Sie stattdessen eine in CP1257 codierte Datei?) – geoffspear

+0

Beim Ausführen von 'sudo file/media/sf_attendance/PREvents.csv' erhalte ich ' /media/sf_attendance/PREvents.csv: ISO-8859-Text, mit CRLF-Zeilenabschlusszeichen' –

+0

ISO-8859 ist eine Familie von Kodierungen; CP1252 ist ähnlich (aber nicht identisch) mit ISO-8859-1, das nur westeuropäische Sprachen unterstützt; CP1257 unterstützt baltische Sprachen. – geoffspear

Antwort

15

CP1252 kann nicht repräsentieren ā; Ihre Eingabe enthält das ähnliche Zeichen â. repr zeigt nur eine ASCII-Darstellung eines Unicode-String in Python 2.x:

>>> print(repr(b'J\xe2nis'.decode('cp1252'))) 
u'J\xe2nis' 
>>> print(b'J\xe2nis'.decode('cp1252')) 
Jânis 
+1

Okay, also die offene Zeile Datei ändern zu 'f = codecs.open (Datei, 'rb', 'cp1257')' und dann 'Druck firstname' zeigt die richtigen "eine" aber jetzt bei der Durchführung von' session.commit() 'I' UnicodeEncodeError bekommen: 'Latin-1' Codec Charakter nicht kodieren, können u '\ u0101' in Position 1: Ordnungszahl nicht in Reichweite (256) ' –

+0

Sie könnten utf-8 als Standard-Codierung für die Datenbank festlegen müssen (Session)? – djc

+0

Yup, habe ich jetzt das Problem gelöst - erforderlich hinzufügen 'convert_unicode = true' bei dem "Motor" in' Motor = create_engine Erstellung (Anschluss, convert_unicode = True) ' –

2

Ich denke u'J\xe2nis' richtig ist, siehe:

>>> print u'J\xe2nis'.encode('utf-8') 
Jânis 

Sind Sie tatsächliche Fehler von SQLAlchemy bekommen oder in Ihrer Anwendung Ausgang ?

+0

Wenn ich' versuchen Vorname = firstname.decode (‘ cp1252 ') 'und dann das in die Datenbank einfügen Ich bekomme immer noch das Zeichen" â " –