как исправить отображение символов в неопределенной ошибке Юникода

0

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

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)
  • 0
    Это, вероятно, проблема вместо апострофов.
  • 0
    @dfundako: '\x92' - ПРАВИЛЬНАЯ ОДНОКВАЖНАЯ МАРКА ЦИТАТЫ ( ' ) в кодировке cp1252
Теги:
csv
unicode

1 ответ

0

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

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

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

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

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

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

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

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 ЗАМЕНЫ ХАРАКТЕР U + FFFD ' ' ' ' для строки юникода.


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

  • 0
    Я обновил вопрос с использованием кода
  • 0
    @ A.Pearson: это Python2 или Python3?
Показать ещё 3 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню