Как ответил AI «Перекодировка SQL-базы данных, в которой строки хранятся в смешанной кодировке, — это сложная задача, которая может возникнуть, например, при миграции данных между системами или при неправильном импорте данных.»
Проблема заключается в том, что разные строки в базе данных могут быть закодированы в разных кодировках (например, часть строк в UTF-8, а часть в Windows-1251). Это приводит к некорректному отображению данных и ошибкам при обработке. Предметно, ситуация случилась с хранилищем OwnCloud, имена файлов превратились в вид «Р›Р°РЅРґС‹С€Рё», но только в базе. Причина произошедшего не установлена и была отложена на неопределённое время. Это время пришло…
Основные проблемы:
- Смешанные кодировки:
- Некоторые строки могут быть закодированы в
UTF-8, а другие — вWindows-1251или другой кодировке. - Это может произойти из-за неправильного импорта данных, ошибок в приложениях или ручного редактирования базы данных.
- Некоторые строки могут быть закодированы в
- Некорректное отображение символов:
- Если данные отображаются как «кракозябры» (например,
ПриветвместоПривет), это указывает на проблему с кодировкой.
- Если данные отображаются как «кракозябры» (например,
- Ошибки при обработке данных:
- Попытка перекодировать строки в единую кодировку может привести к ошибкам, если исходная кодировка строки неизвестна или определена неправильно.
- Потеря данных:
- При неправильной перекодировке часть данных может быть потеряна или искажена, особенно если используются символы, которые не поддерживаются целевой кодировкой.
Подходы к решению проблемы:
- Анализ данных:
- Определить, какие кодировки используются в базе данных. Это можно сделать с помощью анализа символов или инструментов для определения кодировок.
- Мною был задействован онлайн декодер https://involta.ru/tools/decoder/, догадка о UTF-8 и Windows-1251 была подвержена.
- Ручная проверка и исправление:
- Если данных немного, можно вручную проверить и исправить кодировку строк.
- Я исправил несколько строк, проверил всё работает, посмотрев на оставшиеся 5 000+, вспомнил что монотонный труд это не моё.
- Автоматическая перекодировка:
- Совет из интернета №1: вариации на тему iconv, делаем дамп и работаем с ним
iconv -f utf-8 -t latin1 < in.sql | iconv -f cp1251 -t utf-8 > out.sql
илиiconv -f WINDOWS-1251 -t UTF-8 file_in.csv -o file_utf8.csv
не работает, запинаясь в разных частях файла, ругаясь (iconv: недопустимая входная последовательность в позиции 7673). - Совет из интернета №2: вариации на тему recode,
recode windows-1251..utf-8 oc_filecache.csv
не работает, причина та же, запинается из-за смешанных кодировок. - Написать скрипт (например, на Python), который будет анализировать каждую строку, определять её кодировку и перекодировать в целевую кодировку (например,
UTF-8). Понимаю, что это мой вариант.
- Совет из интернета №1: вариации на тему iconv, делаем дамп и работаем с ним
Решение:
- Пошаговое решение:
- Экспортируйте данные из базы в текстовый формат (например, sql).
- Перекодируйте данные с помощью скрипта python (convert.py).
- Импортируйте данные обратно в базу.
- Пьём чай.
- Примечания:
- В дампе sql строки выделены кавычками ‘ ‘ и скрипт настроен на это, при другой конфигурации можете изменить регулярное выражение.
- Запуск скрипта convert.py input.sql output.sql
# Функция для обработки текста
def process_text(text):
# Регулярное выражение для поиска строк в кавычках
pattern = r"'(.*?)'"
# Функция для замены строк
def replace_long_string(match):
string = match.group(1)
utf8_bytes = string.encode('windows-1251')
try:
windows_1251_string = utf8_bytes.decode('utf-8')
except Exception as e:
windows_1251_string = string
return f"'{windows_1251_string}'"
# Заменяем строки в кавычках согласно условию
processed_text = re.sub(pattern, replace_long_string, text)
return processed_text
Скрипт на GitHub.com: https://github.com/DMcraft/convertBaseDump.git