2013-03-19 3 views
16

так хорошо, поскольку заголовок подсказывает, что проблема заключается в правильном чтении ввода из кодированного файла Windows-1252 в python и вставка указанного ввода в таблицу SQLAlchemy-MySql ,Правильное чтение текста из файла Windows-1252 (cp1252) в python

Текущая установка системы:
Windows 7 VM с «системой контроля доступа Roger», которая выводит файл;
Ubuntu 12.04 LTS VM с общей папкой для системы Windows, поэтому я могу получить доступ к файлу с помощью «Python 2.7.3».

Теперь перед фактической проблемой для входного файла у меня есть «общая папка VM», которая содержит файл, который является genereate в системе Windows 7 через Roger Access Control System (roger.pl для более подробной информации), это файл называется «PREvents.csv», который предлагает его содержимое, «;» разделенный список данных.

Пример Формат данных:

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; 

4-поле содержит имя владельцев карт и пятые содержит владелец LastName, 6 содержит владелец назначенной группы.

Проблема исходит из того, что любые один из 3-х указанных выше полей могут содержать символы, характерные для латышского языка, в файл примере слова «Янис» содержит букву «А», который в Юникоде 257.

Как я привык, я открываю файл, например:

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

до сих пор все работает - он открывает файл, и поэтому я перейти на итерацию по каждой строке файла (это непрерывный запуск сценария, так что прошу прощения):

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

И вот где начинаются проблемы, если я print repr(firstname) печатает u'J\xe2nis', который, насколько я понял, не прав - `\ xe2 \ не представляет латышский символ« ā ».
Далее вниз цикл в зависимости от типа события Поручаю переменные для объекта SQLAlchemy и вставки/обновления:

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

В моих поисках ответов я нашел, как определить кодировку по умолчанию для использования:

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

Это никоим образом не помогло мне.

В принципе, это все приводит к тому, я не в состоянии вставить правильные владелец имя/фамилию как хорошо, как владельцы назначены имя_группы, если они содержат какие-либо из латвийско-специфических символов, например:

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

Я также хотел бы добавить, что я не могу изменить кодировку файла «PREvents.csv», а система «RACS» не поддерживает вставку в файлы UTF-8 или Unicode - если вы пытаетесь в любом случае, система вставляет случайные символы для Персонажи, характерные для Латвии.

Пожалуйста, дайте мне сейчас, если нужна любая другая информация, я с удовольствием предоставить ему :)

Любая помощь будет высоко оценен.

+0

Латышский персонаж вообще не доступен в CP1252. Вы не можете создать файл с кодировкой CP1252, содержащий этот символ. (У вас вместо этого есть файл, закодированный в CP1257?) – geoffspear

+0

При выполнении 'sudo file/media/sf_attendance/PREvents.csv' я получаю ' /media/sf_attendance/PREvents.csv: текст ISO-8859 с терминаторами линии CRLF' –

+0

ISO-8859 - это семейство кодировок; CP1252 подобен (но не идентичен) ISO-8859-1, который поддерживает только западноевропейские языки; CP1257 поддерживает балтийские языки. – geoffspear

ответ

15

CP1252 не может представлять собой; ваш вход содержит аналогичный символ â. repr просто отображает ASCII представление Юникода строки в Python 2.x:

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

Итак, изменив открытую строку файла на 'f = codecs.open (файл, 'rb', 'cp1257')', а затем 'print firstname' показывает правильную« ā », но теперь, когда вы выполняете' session.commit() 'Я получаю' UnicodeEncodeError: 'latin-1' codec не может кодировать символ u '\ u0101' в позиции 1: порядковый номер не в диапазоне (256) ' –

+0

Возможно, вам нужно будет установить utf-8 в качестве кодировки по умолчанию для базы данных (сессия)? – djc

+0

Yup, я решил проблему сейчас - вам нужно добавить 'convert_unicode = True' при создании« engine »в' engine = create_engine (connection, convert_unicode = True) ' –

2

Я думаю u'J\xe2nis' правильно, см:

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

Вы получаете фактические ошибки от SQLAlchemy или в выходе вашего приложения ?

+0

Если я попробую' firstname = firstname.decode (' cp1252 ') 'и затем вставить это в базу данных, я до сих пор получаю символ« â » –