Миграция из MySQL в PostgreSQL в Linux (Kubuntu)
давным-давно в системе далеко-далеко...
попытка переноса базы данных из 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 Фея!--70-->.
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
и преобразовать идентификаторы в нижний регистр, и вставить ссылку на схему (используя НАПОР)::%s/"([A-Z_]*)"/L/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
toclimate-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?release_id=810
- http://sqlfairy.sourceforge.net/
спасибо ты!
4 ответов
то, что я обычно делаю для таких миграций, является двукратным:
- извлеките все определение базы данных из MySQL и адаптируйте его к синтаксису PostgreSQL.
- перейдите к определению базы данных и преобразуйте его, чтобы воспользоваться функциональностью в PostgreSQL, которая не существует в MySQL.
затем выполните преобразование и напишите программу на любом языке, который вам наиболее удобен, которая выполняет следующее:
- читает данные из базы данных MySQL.
- выполняет любое преобразование, необходимое для данных, которые будут храниться в базе данных PostgreSQL.
- сохраняет преобразованные данные в базе данных PostgreSQL.
перепроектировать таблицы для PostgreSQL, чтобы воспользоваться его функциями.
Если вы просто делаете что-то вроде использования sed
скрипт для преобразования дампа SQL из одного формата в другой, все, что вы делаете, это помещаете MySQL база данных на сервере PostgreSQL. Вы можете это сделать, и это все равно принесет некоторую пользу, но если вы собираетесь мигрировать, мигрируйте полностью.
это потребует немного больше времени, но я еще не сталкивался с ситуацией, когда это не стоит того.
конвертируйте файл mysqldump в формат PostgreSQL
преобразовать данные следующим образом (не используйте 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
s,varchar
S и float
s.
индексы, первичные ключи и последовательности
С 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
содержащий инструкции create table,/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.
A
--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 to 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()