MySQL -> PostgreSQL.

Автор shurutov, июля 23, 2015, 09:02:46

« назад - далее »

0 Пользователи и 1 гость просматривают эту тему.

shurutov

Перегоняю тут небольшую (~30 млн. записей, 5,5 ГБ дамп) базюльку из мыскля в постгрес. Успешно. Две записи не прошли (неверные юникоды), но ответственные товарищи заявили, что на них можно не обращать внимания. И даже прибить в оригинальной базе. Что я и сделал после их (записей) "изучения". :) Перегонял ручками, потому что:
а) разрабы пришли ко мне, потому что использованные ими средства конвертации ломались на наших тестовых данных (они потом на рабочих данных из более других исходных полей сформировали одно из результирующих полей, так что моя разработка сломалась на рабочих данных);
б) табличек всего две с очень простой схемой, т.е. поправить ручками дамп - это дело одной-двух минут.
Ну и сам процесс:
1. Схема.
1.1. Дамп из мыскля:
mysqldump --compact --compatible=postgresql --no-data <dbname> <table1[ table2...]> -r export-schema.sql
--compact - нам очень не нужно весь и всяческий мусор в дампе, поэтому я считаю данный ключ совершенно необходимым; остальные ключи, я надеюсь, понятно для чего;
1.2. правка дампа для залития в постгрес:
- убрать двойные кавычки из дампа (нафига они нужны, по большому счету?);
- преобразовать int(<циферки>) в bigint (мне повезло, что только в бигинт, на самом деле в куда преобразовывать, зависит от значения <циферки>);
- преобразовать char(<циферки>) в varchar(<циферки>) (просто потому что логика такая, а с приключениями char(<циферки>) в постгресе я уже сталкивался, ага);
соответственно, делается одной командой:
sed -i -e 's/"//g' -e 's/int(11)/bigint/g' -e 's/ (char([0-9]+))/ var\1/' export-schema.sql
После чего export-schema.sql легко и непрнужденно влетает в постгрес.
2. Данные.
2.1. Дамп из мыскля.
for t in <список таблиц>; do mysqldump --compact --compatible=postgresql --default-character-set=utf8 --no-create-info -r <PATHTO>/${t}.sql <dbname> ${t}; done
--compact - см. выше про дамп схемы;
--default-character-set=utf8 - исходная база в cp1251, локаль сервера и результирующая база - utf-8;
--no-create-info - это чтобы для уверенности, однако, ибо создание объектов нафиг не надо;
2.2. Самое интересное - подготовка данных к заливке в постгрес. Сразу скажу - одна таблица влетела безо всяких приключений в силу простоты, а вот со второй пришлось развлечься по-настоящему.
- Удаляем возврат каретки  (мнемокод \r), потому что в какой-то из моментов заливка дампа таблицы на нем сломалась:
sed -i'.1' -e "s/\\\r//g" <PATHTO>/<TABLENAME>.sql
- Включаем экранирование специальных символов обратным слешем, иначе все совсем грустно и печально (можно было, как я уже сильно позже нагуглил, включить такое поведение путем установки соответствующего параметра, но, что сделано, то сделано).
sed -i'.2' -e "s/,'/,E'/g" <PATHTO>/<TABLENAME>.sql
Сейчас попытался найти материал, где указывались команды установки соответствующих параметров, вместо этого нарыл, что таки правильно E'<строка>',  здеся. Хоть и про 9.1, но тем не менее. Кстати, мне в своей практике не доводилось встречать работу со строкамис установкой параметров. А вот с E'<строка>' - изрядно.
- Удаляем нулевой байт (мнемокод \0), на котором заливка дампа также ломалась (привет погромистам, которые лексемы в текстовом поле придумали им разделять в силу своих каких-то соображений)
sed -i'.3' -e "s/\\\0[^']*')/')/g" <PATHTO>/<TABLENAME>.sql
Мне "повезло" в том плане, что надо было оставить только первую лексему в поле. Если бы надо было заменить нулевые байты более другим значением - было бы сильно веселее с регуляркой. Точно говорю! :)
После этого данные за исключением двух строк влетели в постгрес, как так и надо.
Затем начались проверки данных на корректность с приключениями, как же без них-то! Но об этом как-нибудь позже, если совсем будет. Почему погромисты решили сначала съесть мне моСК с переносом данных и только потом начать их (данных) проверку - спрашивайте погромистов и их руководителей.
С уважением,
Шурутов Михаил