Миграция из MySQL в PostgreSQL на Linux (Kubuntu)
-
26-09-2019 - |
Вопрос
Давным-давно на системе далеко, далеко ...
Пытаясь перенести базу данных из MySQL в PostgreSQL. Вся документация я читала чехлы, в значительной степени, как мигрировать структуру. Я нашел очень маленькую документацию по миграции данных. Схема имеет 13 таблиц (которые были успешно мигрированы) и 9 ГБ данных.
MySQL версия: 5.1.x
PostgreSQL версия: 8.4.x
Я хочу использовать язык программирования R, чтобы проанализировать данные с использованием операторов SQL Select; PostgreSQL имеет PL / R, но MySQL не имеет ничего (насколько я могу сказать).
Новая надежда
Создайте местоположение базы данных (/var
имеет недостаточное пространство; Также не нравится иметь номер версии PostgreSQL везде - модернизация сломала бы сценарии!):
sudo mkdir -p /home/postgres/main
sudo cp -Rp /var/lib/postgresql/8.4/main /home/postgres
sudo chown -R postgres.postgres /home/postgres
sudo chmod -R 700 /home/postgres
sudo usermod -d /home/postgres/ postgres
Все хорошо здесь. Затем перезагрузите сервер и настройте базу данных, используя эти инструкции по установке:
sudo apt-get install postgresql pgadmin3
sudo /etc/init.d/postgresql-8.4 stop
sudo vi /etc/postgresql/8.4/main/postgresql.conf
- Сдача
data_directory
к/home/postgres/main
sudo /etc/init.d/postgresql-8.4 start
sudo -u postgres psql postgres
\password postgres
sudo -u postgres createdb climate
pgadmin3
Использовать pgadmin3
Чтобы настроить базу данных и создать схему.
Эпизод продолжается в удаленной оболочке, известной как bash
, с обоими базами данных, и установка набора инструментов с довольно необычным логотипом: SQL Fairy..
perl Makefile.PL
sudo make install
sudo apt-get install perl-doc
(странно, это не называетсяperldoc
)perldoc SQL::Translator::Manual
Извлечь PostgreSQL-дружественный DDL и все MySQL
данные:
sqlt -f DBI --dsn dbi:mysql:climate --db-user user --db-password password -t PostgreSQL > climate-pg-ddl.sql
- Редактировать
climate-pg-ddl.sql
и преобразовать идентификаторы в нижний регистр и вставьте ссылку на схему (используя VIM)::%s/"\([A-Z_]*\)"/\L\1/g
:%s/ TABLE / TABLE climate./g
:%s/ on / on climate./g
mysqldump --skip-add-locks --complete-insert --no-create-db --no-create-info --quick --result-file="climate-my.sql" --databases climate --skip-comments -u root -p
Может быть, стоит просто переименовать таблицы и столбцы в MySQL в нижнем регистре:
select concat( 'RENAME TABLE climate.', TABLE_NAME, ' to climate.', lower(TABLE_NAME), ';' ) from INFORMATION_SCHEMA.TABLES where TABLE_SCHEMA='climate';
- Выполните команды с предыдущего шага.
- Вероятно, есть способ сделать то же самое для колонн; Я изменил их вручную, потому что это было быстрее, чем выяснить, как написать запрос.
База данных ударяет обратно
Воссоздать структуру в PostgreSQL следующим образом:
pgadmin3
(переключиться на него)- Нажмите Выполнить произвольные SQL-запросы икона
- Открытым
climate-pg-ddl.sql
- Ищи
TABLE "
заменитьTABLE climate."
(Вставьте имя схемыclimate
) - Ищи
on "
заменитьon climate."
(Вставьте имя схемыclimate
) - Нажимать
F5
выполнить
Это приводит к:
Query returned successfully with no result in 122 ms.
Ответы джедаев
На данный момент я втуман.
- Откуда мне идти отсюда (Какие шаги) для преобразования
climate-my.sql
кclimate-pg.sql
Так что они могут быть выполнены против PostgreSQL? - Как я убедиться, что индексы будут скопированы правильно (для поддержания референциальной целостности; у меня нет ограничений на данный момент, чтобы облегчить переход)?
- Как мне убедиться, что добавление новых строк в PostGreSQL начнет перечислять из индекса вставленной последней строки (и не конфликт с существующим первичным ключом из последовательности)?
- Как вы убедитесь, что имя схемы происходит при преобразовании данных из MySQL в PostgreSQL вставки?
Ресурсы
Была необходима справедливая информация о том, чтобы получить это далеко:
- https://help.ubuntu.com/community/postgresql.
- http://articles.sitepoint.com/article/site-mysql-postgresql-1
- http://wiki.postgresql.org/wiki/Converting_from_Other_databases_to_postgresql#mysql.
- http://pgfoundry.org/frs/shownotes.php?relase_id=810.
- http://sqlfairy.sourceforge.net/
Благодарю вас!
Решение
То, что я обычно делаю для таких миграций, это два раза:
- Извлеките все определение базы данных из MySQL и адаптируйте его к синтаксису PostgreSQL.
- Перейдите по определению базы данных и преобразуйте его, чтобы воспользоваться функциональностью в PostgreSQL, которая не существует в MySQL.
Затем сделайте преобразование и напишите программу на любом языке, с которым вам наиболее удобно, чтобы выполнила следующее:
- Читает данные из базы данных MySQL.
- Выполняет любую трансформацию, необходимую для хранения данных в базе данных PostgreSQL.
- Сохраняет сейчас преобразованные данные в базе данных PostgreSQL.
Передирайте таблицы для PostgreSQL, чтобы воспользоваться его функциями.
Если вы просто сделаете что-то вроде, используйте sed
Скрипт Для преобразования дамп SQL из одного формата на следующий, все, что вы делаете, это поместит базу данных MySQL в PostgreSQL Server. Вы можете сделать это, и все равно будет иметь некоторую выгоду от этого, но если вы собираетесь мигрировать, мигрировать полностью.
Он будет включать в себя немного большее время, но мне еще предстоит ситуацию, когда она не стоит этого.
Другие советы
Преобразовать файл MySQLDUM на PostgreSQL Format
Преобразуйте данные следующим образом (не используйте mysql2pgsql.perl.):
Избежать цитат.
sed "s/\\\'/\'\'/g" climate-my.sql | sed "s/\\\r/\r/g" | sed "s/\\\n/\n/g" > escaped-my.sql
Заменить
USE "climate";
С пути поиска и комментировать комментарии:sed "s/USE \"climate\";/SET search_path TO climate;/g" escaped-my.sql | sed "s/^\/\*/--/" > climate-pg.sql
Подключиться к базе данных.
sudo su - postgres
psql climate
Установите кодировку (mysqldump игнорирует свой параметр кодирования), а затем выполнить скрипт.
\encoding iso-8859-1
\i climate-pg.sql
Эта серия шагов, вероятно, не будет работать для сложных баз данных со многими смешанными типами. Тем не менее, это работает для integer
с varchar
песок float
с.
Индексы, первичные ключи и последовательности
С mysqldump
включал основные ключи при генерировании INSERT
заявления, они будут превзойти автоматическую последовательность таблицы. Последовательности для всех таблиц остались 1 при проверке.
Установите последовательность после импорта
Используя ALTER SEQUENCE
Команда установит их на все необходимое значение.
Префикс схемы
Нет необходимости префиксировать таблицы с именем схемы. Использовать:
SET search_path TO climate;
Если вы преобразовали схему, то мигрирующие данные будут простой частью:
Схема скидки от PostgreSQL (вы сказали, что вы преобразовали схему в Postgres, поэтому мы будем бросить его сейчас, так как мы будем удалять и воссоздать целевую базу данных, чтобы она очистила):
pg_dump dbname > /tmp/dbname-schema.sql
Схема схемы до 2 частей -
/tmp/dbname-schema-1.sql
Содержащие отчетности создания таблицы,/tmp/dbname-schema-2.sql
- остальное. PostgreSQL должен импортировать данные перед зарубежными ключами, импортируются триггеры и т. Д., Но после определения таблиц импортируются.Создайте базу данных только с 1 частью схемы:
drop database dbname create database dbname \i /tmp/dbname-schema-1.sql -- now we have tables without data, triggers, foreign keys etc.
Импорт данных:
( echo 'start transaction'; mysqldump --skip-quote-names dbname | grep ^INSERT; echo 'commit' ) | psql dbname -- now we have tables with data, but without triggers, foreign keys etc.
А.
--skip-quote-names
Опция добавляется в MySQL 5.1.3, поэтому, если у вас есть старая версия, то установите новее mysql временно в/tmp/mysql
(configure --prefix=/tmp/mysql && make install
должен сделать) и использовать/tmp/mysql/bin/mysqldump
.Импортировать остальную часть схемы:
psql dbname start transaction \i /tmp/dbname-schema-2.sql commit -- we're done
Проверить etlalchemy. Отказ Это позволяет вам мигрировать из MySQL к PostgreSQL., или между несколькими другими базами данных, в 4 строках Python. Вы можете прочитать больше об этом здесь.
Установить: pip install etlalchemy
Бежать:
from etlalchemy import ETLAlchemySource, ETLAlchemyTarget
# Migrate from MySQL to PostgreSQL
src = ETLAlchemySource("mysql://user:passwd@hostname/dbname")
tgt = ETLAlchemyTarget("postgresql://user:passwd@hostname/dbname",
drop_database=True)
tgt.addSource(src)
tgt.migrate()