Проблема с преобразованием польских символов (ISO-8859-2) в Postgres с кодировкой UTF-8 в Python

Что касается проекта, над которым я работаю, у меня есть много файлов .unl (informix) для разных стран, и их необходимо импортировать в postgres. Для этого мне нужно перевести схему Informix в схему Postgres с помощью Python.

Предполагая, что в моем скрипте Python есть эта строка кода, с помощью которой я хочу открыть все файлы .unl:

open(file, 'r', encoding='latin1')

В странах, где используется encoding = latin1, скрипт работает нормально, и в Postgres все выглядит хорошо. За исключением Польши

Когда я указываю encoding = latin2 для Польши, скрипт импорта по-прежнему успешно выполняется, но польский текст в Postgres выглядит по-другому. Например, вывод неожиданно выглядит так:

Но если кодировка правильная, ожидаемый результат должен выглядеть так:

Я попробовал и до сих пор не могу понять, как это исправить. Я очень ценю любые предложения о том, как решить эту проблему. Заранее спасибо!

как и для всех вопросов такого рода, посмотрите на необработанное байтовое представление файла/строки и проверьте фактическую кодировку, исследуя байты некоторых специальных символов, если файл действительно соответствует ISO-8859. -2 тогда open('file', 'r', encoding='ISO-8859-2') должно работать

jhole 27.05.2024 18:36

Опубликуйте минимальный воспроизводимый пример включая образец файла. Вы проверили локаль базы данных с помощью sysdbslocale?

relent95 28.05.2024 03:28

Определенно похоже на проблему с кодировкой символов, но ваш пример не имеет особого смысла. Попробуйте запустить этот код во входном файле на польском языке: stackoverflow.com/a/1779263/5987

Mark Ransom 28.05.2024 03:54

Не верьте, что до или после не было никаких обращений. Возможно, исходные данные были латиницей-2, но при «копировании файлов» было недокументированное перекодирование. То же самое и с выводом: не ожидайте, что все программы знают выходную кодировку для правильного отображения (кодировка — это метаданные, поэтому такие данные теряются или не передаются между программами). Итак, первый комментарий: проверьте raw байты: прочитайте как двоичные и выведите значения каждого символа (и, возможно, некоторых старых страниц cp (то есть со всеми символами с другим и определенным числом, а также в управляющих кодах): это помогает найти, где находится проблема в том, что без предположения

Giacomo Catenazzi 28.05.2024 14:30

Благодарим всех за то, что поделились своими мыслями. Теперь эта проблема решена.

user25273768 29.05.2024 12:41
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
5
102
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы столкнулись с вопиющим случаем моджибаке.

Доказательство в следующем (частично прокомментированном) фрагменте кода: type .\SO\78540135.py

file = r'.\SO\78540135.txt'
str_text = 'Aleksańdra Świętochowskiego'

# create a sample file: utf-8 encoded
with open( file, 'w', encoding = 'utf-8') as f:
    f.write( str_text)

# read the file using wrong encoding
with open( file, 'r', encoding = 'latin2') as f:
    str_name = f.read()

print( '\nmojibake', str_name)

# read the file using correct encoding
with open( file, 'r', encoding = 'utf-8') as f:
    str_name = f.read()

print( '\nUTF8text', str_name)

Вывод: python .\SO\78540135.py

mojibake AleksaĹdra ĹwiÄtochowskiego

UTF8text Aleksańdra Świętochowskiego

Спасибо @JosefZ за то, что рассказал мне об этом, и да, это проблема моджибаке. Благодаря вашему упоминанию я нашел решения. Еще раз спасибо!

user25273768 29.05.2024 12:40

@ Lotus1989 отлично! чтобы помочь сообществу и заработать немного репутации, отметьте это как ответ, поставив галочку слева.

ti7 29.05.2024 18:28

Меня смутил тот факт, что ожидаемая строка и результат моджибаке были одинаковой длины; Я предполагал, что преобразование в UTF-8 удлинит строку. Так и есть, но оказывается, что некоторые символы, полученные после декодирования latin2, невидимы!

Mark Ransom 30.05.2024 23:49

@MarkRansom да, эти невидимки — это элементы управления между \x80 и \x9F. На самом деле, 'ń Ś ę'.encode( 'utf-8').decode( 'latin2') -> 'Ĺ\x84 Ĺ\x9a Ä\x99' однако print( 'Ĺ\x84 Ĺ\x9a Ä\x99') -> Ĺ Ĺ Ä

JosefZ 31.05.2024 18:34

Другие вопросы по теме