7

При получении данных из таблицы MySQL (используя Connector/Python) текстовые строки имеют вид:

Калашникова Елена Сергеевна

и

Тищенко Ð\x90ндрей ВаÑ\x81ильевич

Декодер показывает, что это кодировка CP1252, поэтому в Python3 мы можем обработать их str.encode('cp1252').decode('utf8'), однако если этот метод работает для первой строки, то не работает для второй.

UnicodeEncodeError: 'charmap' codec can't encode character '\x90' in position 16: character maps to undefined

Проблема - в специальных символах \x90, \x9D, \x8F, \x8D, \x81. В описании Windows-1252 указано, что эти коды относятся к C1 control codes.

Каким образом можно декодировать эти строки в Python3, не изменяя базу MySQL? Или где ещё может быть источник проблемы?

jfs
  • 52,361
  • Вы уверены, что данные в базе записаны "правильно"? Проверяли сторонними утилитами? – KoVadim Jun 30 '15 at 08:18
  • А нельзя данные сразу в utf-8 читать? – Qwertiy Jun 30 '15 at 08:21
  • 1
    попробуйте явно указать charset (utf8) при подключении к базе данных. – aleksandr barakin Jun 30 '15 at 08:22
  • База - реально действующая, работающая. В программе, для которой она написана, всё отображается верно и кириллицей. При импорте данных получаю такие строки. Натыкался, что подобное встречается, но решения на ruby не понял. – Illia Ilin Jun 30 '15 at 08:22
  • А можно вывод print(repr(строка))? – andreymal Jun 30 '15 at 08:33
  • При print(repr(str)) Получаются такие же результаты ровным счётом: Тищенко Ð\x90ндрей ВаÑ\x81ильевич

    Указывать явно кодировку базы при импорте пробовал - cp1252 в списке кодировок нет, utf8 даёт такой вот точно результат, что и описан.

    – Illia Ilin Jun 30 '15 at 08:37
  • Интересно, что TABLE_COLLATION у таблицы - utf8_general_ci, и консольный вывод в mysql SELECT * FROM table_name я получаю такими же кракозябрами. В то же время она прекрасно выводится кириллицей в программе, для которой написана. Загадка неживой природы) – Illia Ilin Jun 30 '15 at 09:00
  • @ilyinilyas, верноятно, в программе приделан по этому поводу «костыль». – aleksandr barakin Jun 30 '15 at 09:42
  • Нашёл решение и уже написал ответ) Положился на декодер, и поверил, что там cp1252, хотя такой кодировки нет среди поддерживаемых MySQL. – Illia Ilin Jun 30 '15 at 09:46
  • похожий (часть про кракозябы) вопрос: Проблемы с кодировкой Python 2.7 – jfs Jul 23 '15 at 07:06

1 Answers1

5

Нашёл ответ!)
При импорте базы данных нужно использовать кодировку latin1 Тогда в Python3 для декодирования таких строк необходимо выполнить str.encode('latin1').decode('utf8').
На решение натолкнула эта статья - Solving Latin1 and UTF8 errors for good in Ruby:

Latin1 is a character encoding used by MySQL. People mistakenly think it is equivalent to ISO-8859-1 but it isn’t, it’s actually CP-1252 (also known as Windows-1252). CP-1252 is a superset of ISO-8859-1 with some additional characters (recently including the € symbol).

Соответcnвенно, я нашёл в списке поддерживаемых кодировок latin1, и использовал её при подключении к MySQL с помощью Connector/Python.