2013-03-19 11 views
16

così bene, come suggerisce il titolo il problema che ho è con la lettura corretta dell'input da un file codificato Windows-1252 in python e l'inserimento di detto input nella tabella SQLAlchemy-MySql .Correttamente leggendo il testo dal file Windows-1252 (cp1252) in python

L'attuale configurazione di sistema:
Windows 7 VM con "Roger Access Control System" che emette il file;
Ubuntu 12.04 LTS VM con una cartella condivisa per il sistema Windows in modo da poter accedere al file, utilizzando "Python 2.7.3".

Ora per il problema reale, per il file di input ho una "cartella condivisa VM" che contiene un file che è genereato su un sistema Windows 7 tramite Roger Access Control System (roger.pl per maggiori dettagli), questo il file si chiama "PREvents.csv" che suggerisce al suo contenuto, un ";" elenco separato di dati.

Un formato esempio di dati:

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; 

Il quarto campo contiene il nome possessori di schede e 5 contiene i proprietari cognome, il 6 contiene il gruppo assegnato proprietari.

Il problema deriva dal fatto che uno qualsiasi dei 3 campi di cui sopra possono contenere caratteri specifici di lingua lettone, nel file di esempio la parola "Jānis" contiene la lettera "A", che in unicode è 257.

come io sono abituato, ho aperto il file in quanto tale:

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

Finora, tutto funziona - si apre il file e quindi passare a iterare su ogni riga del file (questo è un script in esecuzione continua così perdonare il ciclo):

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

E questo è dove iniziano i problemi, se io print repr(firstname) stampa u'J\xe2nis' che è, per quanto ho capito, non corretto - `\ xe2 \ non rappresenta il carattere lettone" ā ".
Più in basso il ciclo in base al tipo di evento assegno le variabili di opporsi SQLAlchemy e inserimento/aggiornamento:

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

Nella mia ricerca di risposte che ho trovato come definire la codifica di default da utilizzare:

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

Che non mi ha aiutato in alcun modo.

Fondamentalmente, questo è tutto conduce al me non essere in grado di inserire i proprietari corretti Nome/Cognome costavano come proprietari assegnati nomegruppo se contengono dei caratteri lettone-specifici, ad esempio:

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

Vorrei anche aggiungere che non posso cambiare la codifica dei file "PREvents.csv" e che il sistema "RACS" non supporta l'inserimento nei file UTF-8 o Unicode - se provi in ​​entrambi i casi, il sistema inserisce simboli casuali per Caratteri specifici lettoni.

Siete pregati di me ora se è necessaria qualsiasi altra informazione, sarò contento di fornirlo :)

Qualsiasi aiuto sarebbe molto apprezzato.

+0

Il carattere lettone ā non è disponibile in CP1252. Non è possibile creare un file codificato CP1252 che contenga quel carattere. (Avete invece un file codificato in CP1257?) – geoffspear

+0

Quando eseguite 'sudo file/media/sf_attendance/PREvents.csv' ottengo ' /media/sf_attendance/PREvents.csv: testo ISO-8859, con terminatori di riga CRLF' –

+0

ISO-8859 è una famiglia di codifiche; CP1252 è simile (ma non identico a) ISO-8859-1, che supporta solo le lingue dell'Europa occidentale; CP1257 supporta le lingue baltiche. – geoffspear

risposta

15

CP1252 non può rappresentare ā; il tuo input contiene il personaggio simile â repr solo visualizza una rappresentazione ASCII di una stringa Unicode in Python 2.x:

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

Ok, cambiando la riga aperta del file in 'f = codecs.open (file, 'rb', 'cp1257')' e poi 'print firstname' mostra il corretto "ā" ma ora quando si esegue 'session.commit() 'Ottengo' UnicodeEncodeError: 'latin-1' codec non può codificare il carattere u '\ u0101' in posizione 1: ordinal non nel range (256) ' –

+0

Potrebbe essere necessario impostare utf-8 come codifica predefinita per il database (sessione)? – djc

+0

Sì, ho risolto il problema ora - necessario aggiungere 'convert_unicode = True' quando si crea il" motore "in' engine = create_engine (connection, convert_unicode = True) ' –

2

Credo u'J\xe2nis' è corretto, si veda:

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

State ottenendo errori effettivi da SQLAlchemy o in uscita dell'applicazione ?

+0

Se provo' firstname = firstname.decode (' cp1252 ') 'e poi lo inserisco nel database Ho ancora il carattere" â " –

Problemi correlati