2013-03-19 18 views
16

, więc dobrze, ponieważ tytuł sugeruje, że mam problem z poprawnym odczytaniem danych wejściowych z zakodowanego pliku windows-1252 w pythonie i wstawienia tego wejścia do tabeli SQLAlchemy-MySql .Prawidłowe czytanie tekstu z pliku Windows-1252 (cp1252) w pythonie

Obecna konfiguracja systemu:
Windows 7 VM z systemem "Roger Access Control", która wyprowadza plik;
Ubuntu 12.04 LTS VM z udostępnionym folderem do systemu Windows, więc mogę uzyskać dostęp do pliku, używając "Python 2.7.3".

Teraz problem z plikiem wejściowym Mam "udostępniony folder VM", który zawiera plik, który jest zapisany w systemie Windows 7 przez Roger Access Control System (roger.pl po więcej szczegółów), to plik nazywa się "PREvents.csv", co sugeruje jego zawartość, ";" oddzielna lista danych.

Przykładowy format danych:

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; 

4th pole zawiera nazwę właścicieli kart i 5 zawiera właściciele Nazwisko, 6. zawiera właściciele przypisaną grupę.

Problem wynika z faktu, że każdy z 3 wymienionych wyżej dziedzinach mogą zawierać znaków specyficznych dla języka łotewskiego, w przykładzie plik słowo „Jānis” zawiera literę „A”, które w Unicode jest 257.

Ponieważ jestem przyzwyczajony do, otwierania pliku, takie jak:

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

jak dotąd, wszystko działa - otwiera plik, a więc przejść do iteracyjne nad każdym wierszu pliku (jest to skrypt ciągły, więc przepraszam za pętlę):

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

I tu zaczynają się problemy, jeśli I print repr(firstname) drukuje u'J\xe2nis', co jest, o ile nieumiejętne, niepoprawne - `\ xe2 \ nie reprezentuje łotewskiego znaku" ā ".
Dalej pętla w zależności od rodzaju zdarzenia przypisać zmienne do obiektu sqlalchemy i włożyć/aktualizacji:

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

W moim poszukiwaniu odpowiedzi Znalazłem sposób definiowania domyślnego kodowania użyć:

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

Co nie pomogło mi w żaden sposób.

W zasadzie, to wszystko prowadzi do mnie nie jest w stanie wstawić odpowiednie właścicieli imię/nazwisko aswell jako właściciele przypisany groupname jeśli zawierają którykolwiek łotewski specyficznych znaków, na przykład:

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

Chciałbym również dodać, że nie mogę zmienić kodowania pliku "PREvents.csv", a system "RACS" nie obsługuje wstawiania do plików UTF-8 lub Unicode - jeśli spróbujesz w dowolny sposób, system wstawia losowe symbole dla Znaki łotewskie.

proszę niech mi teraz, czy jakiekolwiek inne informacje są potrzebne, będę chętnie dostarczyć :)

Każda pomoc będzie bardzo mile widziane.

+0

Łotewski charakter ā nie jest w ogóle dostępny w CP1252. Nie można utworzyć pliku z kodowaniem CP1252, który zawiera tę postać. (Czy zamiast tego masz plik zakodowany w CP1257?) – geoffspear

+0

Podczas wykonywania 'sudo file/media/sf_attendance/PREvents.csv' otrzymuję ' /media/sf_attendance/PREvents.csv: tekst ISO-8859, z terminatorami linii CRLF'' –

+0

ISO-8859 to rodzina kodowań; CP1252 jest podobny (ale nie identyczny) z ISO-8859-1, który obsługuje tylko języki zachodnioeuropejskie; CP1257 obsługuje języki bałtyckie. – geoffspear

Odpowiedz

15

CP1252 nie może reprezentować ā; twoje wejście zawiera podobny znak - repr tylko wyświetla reprezentację ASCII ciąg Unicode w Pythonie 2.x:

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

OK, więc zmiana otwartej linii pliku na 'f = codecs.open (file, 'rb', 'cp1257')', a następnie 'print firstname' pokazuje prawidłowe" ā ", ale teraz, gdy wykonuję' session.commit() 'Otrzymuję' UnicodeEncodeError: 'kodek Latin-1' nie może kodować znaku u '\ u0101' na pozycji 1: porządkowy nie w zakresie (256) ' –

+0

Może być konieczne ustawienie utf-8 jako domyślnego kodowania dla bazy danych (sesja)? – djc

+0

Tak, już rozwiązałem problem - konieczne jest dodanie 'convert_unicode = True' podczas tworzenia" silnika "w' engine = create_engine (connection, convert_unicode = True) ' –

2

myślę u'J\xe2nis' jest prawidłowa, patrz:

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

Czy otrzymujesz rzeczywistych błędów z SQLAlchemy lub produkcji danej aplikacji ?

+0

Jeśli spróbuję' firstname = firstname.decode (' cp1252 ') ', a następnie wstaw to do bazy danych, nadal otrzymuję znak" â " –