как исправить отображение символов в неопределенной ошибке Юникода - PullRequest
0 голосов
/ 02 июля 2018

Я пытаюсь сделать CSV из некоторых данных из базы данных, чтобы переместить их в облако в хранилище данных. Однако, когда я запускаю его, он всегда завершает работу после 36 599 строк и дает мне

UnicodeEncodeError: 'charmap' codec can't encode character '\x92' in position 62: character maps to <undefined>

Я обнаружил, что причиной, вызывающей проблему, является 'Отклоненный номер дела не совпадает', и я предполагаю, что это проблема с апострофом. Я не знаю, почему это вызывает эту проблему, и я не смог найти способ обойти это. Кто-нибудь знает как это решить? Код, который я использую:

db = pymysql.connect(host='host', port=3306, user="user", passwd="secret", 
db="db", autocommit=True)
cur = db.cursor()
#cur.execute("call inv1_view_prod.`Email_agg`")

cur.execute("""select fields from table""") 


emails = cur.fetchall()
with open('O:\file\path\to\File_name.csv','w') as fileout:
        writer = csv.writer(fileout)
        writer.writerows(emails)   
time.sleep(1)

1 Ответ

0 голосов
/ 02 июля 2018

Поскольку вы не показали код, который вызывает ошибку, я просто догадываюсь.

Единственным фактом является то, что эта строка 'Rejected-Case No. doesn’t match' содержит "’", который является символом Unicode U + 2019, ПРАВИЛЬНАЯ ОДНОКВАЖНАЯ МАРКА ЦИТАТЫ. В кодовой странице windows cp1252 этот символ действительно имеет код 0x92.

Похоже, у вас есть где-то строка байтов, закодированная в кодировке cp1252, которая не была правильно декодирована в строку Unicode.

Что должно быть сделано:

Есть решения. К сожалению, они будут зависеть от используемой вами версии Python (2 или 3), и, ничего не зная о коде, я могу дать только общие советы:

  • идентифицирует входную кодировку (что база данных дает скрипту Python)
  • идентифицирует выходную кодировку (что вы хотите написать в модуле CSV)
  • использовать явные преобразования, чтобы иметь возможность передавать правильные кодировки
  • дополнительно используйте error=replace в вызовах кодирования / декодирования, чтобы избежать исключений UnicodeError.

Если вы используете Python3, я предполагаю, что у вас есть проблема с декодированием Unicode из базы данных. ПРАВИЛЬНАЯ ОДНОКВАЖНАЯ МАРКА ЦИТАТЫ имеет код Unicode U + 2019, но в строке, передаваемой Python, кодируется '\x92', что является кодировкой байтов cp1252. Быстрое и грязное исправление состоит в том, чтобы заставить проход кодирования / декодирования получить правильную строку Unicode. Ваш код может стать:

db = pymysql.connect(host='host', port=3306, user="user", passwd="secret", 
db="db", autocommit=True)
cur = db.cursor()
#cur.execute("call inv1_view_prod.`Email_agg`")

cur.execute("""select fields from table""") 

charset = 'cp1252'   # or 'utf8' depending on what you want in the csv file
with open('O:\file\path\to\File_name.csv','w', encoding=charset,
           errors='replace', newline='') as fileout:
        writer = csv.writer(fileout)
        for row in cur.fetchall():
            writer.writerow([field.encode('latin1').decode('cp1252', errors='replace')
                for field in row])

encode('latin1').decode('cp1252') - это просто хитрость для исправления строки Python3, где символы имеют код байтовой кодировки. Это работает, потому что кодировка latin1 запрещена для всех кодов до 256.

Опция errors=replace, попросить Python никогда не вызывать исключение UnicodeError, но вместо этого заменить заменяющий символ символ '?' для строки байтов или с официальным символом Unicode REPLACEMENT CHARACTER U + FFFD '�' для строки Unicode .


Возможно, было бы чище использовать charset вариант pymysql.connect. К сожалению, я никогда не использовал базы данных MySQL из Python ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...