UnicodeDecodeError: кодек 'ascii' не может декодировать байт 0x92 в позиции 47: порядковый номер не в диапазоне (128)

Я пытаюсь записать данные в объект StringIO с помощью Python, а затем в конечном итоге загрузить эти данные в базу данных postgres, используя функцию copy_from () psycopg2.

Сначала, когда я это сделал, copy_from () выкидывал ошибку: ERROR: неверная последовательность байтов для кодирования «UTF8»: 0xc92 Итак, я последовал этому вопросу .

Я понял, что моя база данных Postgres имеет кодировку UTF8.

Объект file / StringIO, в который я пишу свои данные, показывает свою кодировку следующим образом: setgid Не-ISO расширенный ASCII текст на английском языке, с очень длинными строками, с терминаторами строк CRLF

Я попытался кодировать каждую строку, которую я пишу, в файл промежуточного файла / StringIO в формате UTF8. Для этого используется .encode (encoding = 'UTF-8', errors = 'strict')) для каждой строки.

Это ошибка, которую я получил сейчас: UnicodeDecodeError: кодек ascii не может декодировать байт 0x92 в позиции 47: порядковый номер не в диапазоне (128)

Что это значит? Как это исправить?

EDIT: Я использую Python 2.7 Некоторые части моего кода:

Я прочитал из базы данных MySQL, которая имеет данные, закодированные в UTF-8, в соответствии с MySQL Workbench. Это несколько строк кода для записи моих данных (полученных из MySQL db) в объект StringIO:

# Populate the table_data variable with rows delimited by \n and columns delimited by \t row_num=0 for row in cursor.fetchall() : # Separate rows in a table by new line delimiter if(row_num!=0): table_data.write("\n") col_num=0 for cell in row: # Separate cells in a row by tab delimiter if(col_num!=0): table_data.write("\t") table_data.write(cell.encode(encoding='UTF-8',errors='strict')) col_num = col_num+1 row_num = row_num+1 

Это код, который записывает в базу данных Postgres из моего объекта StringIO table_data:

 cursor = db_connection.cursor() cursor.copy_from(table_data, <postgres_table_name>) 

  • Персистент UTF-8 как кодировка по умолчанию
  • Почему sys.getdefaultencoding () отличается от sys.stdout.encoding и как это прерывает строки Unicode?
  • Печать символов unicode в stdout в python печатает неправильные символы
  • One Solution collect form web for “UnicodeDecodeError: кодек 'ascii' не может декодировать байт 0x92 в позиции 47: порядковый номер не в диапазоне (128)”

    Проблема в том, что вы вызываете encode на объект str .

    Строка является байтовой строкой, обычно представляющей текст, закодированный каким-то образом, как UTF-8. Когда вы вызываете encode на этом, его сначала нужно декодировать обратно в текст, поэтому текст можно перекодировать. По умолчанию Python делает это, вызывая s.decode(sys.getgetdefaultencoding()) , и getdefaultencoding() обычно возвращает 'ascii' .

    Итак, вы говорите кодированный текст UTF-8, декодируя его, как если бы он был ASCII, а затем перекодировал его в UTF-8.

    Общее решение заключается в явном вызове decode с правильной кодировкой вместо того, чтобы позволить Python использовать значение по умолчанию, а затем encode результат.

    Но когда правильная кодировка уже является той, которую вы хотите, проще всего просто пропустить .decode('utf-8').encode('utf-8') и просто использовать UTF-8 str в качестве UTF- 8 str что он уже есть.

    Или, альтернативно, если ваша оболочка MySQL имеет функцию, позволяющую вам указать кодировку и вернуть значения unicode для столбцов CHAR / VARCHAR / TEXT вместо значений str (например, в MySQLdb, вы передаете use_unicode=True для вызова connect или charset='UTF-8' если ваша база данных слишком стар, чтобы автоматически обнаружить ее), просто сделайте это. Тогда у вас будут объекты unicode , и вы можете называть их .encode('utf-8') .

    В общем, лучший способ справиться с проблемами Unicode – это последний раз-декодировать все как можно раньше, выполнять всю обработку в Юникоде, а затем кодировать как можно позже. Но в любом случае, вы должны быть последовательными. Не называть str что-то, что может быть unicode ; не связывать строковый литерал с unicode или передавать его методу replace ; и т. д. Каждый раз, когда вы смешиваете и сопоставляете, Python будет неявно конвертировать для вас, используя стандартную кодировку, которая почти никогда не нужна вам.

    В качестве побочного примечания это одна из многих вещей, с которыми справляется Unicode Python 3.x. Во-первых, str теперь является текстом Unicode, а не закодированными байтами. Что еще более важно, если вы закодировали байты, например, в объекте bytes , вызов encode даст вам AttributeError вместо того, чтобы пытаться тихо декодировать, чтобы он мог перекодировать. И аналогичным образом попытка скомбинировать и сопоставлять Unicode и байты даст вам очевидный TypeError , вместо неявного преобразования, которое в некоторых случаях преуспевает и дает загадочное сообщение о кодировании или декодировании, о котором вы не просили в других.

    Python - лучший язык программирования в мире.