Миграция из 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 везде - обновление сломается сценарии!):

  1. sudo mkdir -p /home/postgres/main
  2. sudo cp -Rp /var/lib/postgresql/8.4/main /home/postgres
  3. sudo chown -R postgres.postgres /home/postgres
  4. sudo chmod -R 700 /home/postgres
  5. sudo usermod -d /home/postgres/ postgres

все хорошо здесь. Затем перезапустите сервер и настройте базу данных с помощью этих инструкция по установке:

  1. sudo apt-get install postgresql pgadmin3
  2. sudo /etc/init.d/postgresql-8.4 stop
  3. sudo vi /etc/postgresql/8.4/main/postgresql.conf
  4. изменить data_directory для /home/postgres/main
  5. sudo /etc/init.d/postgresql-8.4 start
  6. sudo -u postgres psql postgres
  7. password postgres
  8. sudo -u postgres createdb climate
  9. pgadmin3

использовать pgadmin3 для настройки базы данных и создания схемы.

эпизод продолжается в удаленной оболочке, известной как bash, с обеими запущенными базами данных и установкой набора инструментов с довольно необычным логотипом:среда SQL Фея!--70-->.

  1. perl Makefile.PL
  2. sudo make install
  3. sudo apt-get install perl-doc (как ни странно, это не называется perldoc)
  4. perldoc SQL::Translator::Manual

извлеките дружественный к PostgreSQL DDL и все MySQL данные:

  1. sqlt -f DBI --dsn dbi:mysql:climate --db-user user --db-password password -t PostgreSQL > climate-pg-ddl.sql
  2. редактировать climate-pg-ddl.sql и преобразовать идентификаторы в нижний регистр, и вставить ссылку на схему (используя НАПОР):
    • :%s/"([A-Z_]*)"/L/g
    • :%s/ TABLE / TABLE climate./g
    • :%s/ on / on climate./g
  3. 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 в нижний регистр:

  1. select concat( 'RENAME TABLE climate.', TABLE_NAME, ' to climate.', lower(TABLE_NAME), ';' ) from INFORMATION_SCHEMA.TABLES where TABLE_SCHEMA='climate';
  2. выполните команды с предыдущего шага.
  3. вероятно, существует способ сделать то же самое для столбцов; я изменил их вручную, потому что это было быстрее, чем выяснить, как напишите запрос.

База Данных Наносит Ответный Удар

воссоздайте структуру в PostgreSQL следующим образом:

  1. pgadmin3 (переключиться на него)
  2. выберите выполнить произвольные SQL-запросы
  3. открыть climate-pg-ddl.sql
  4. искать TABLE " заменить на TABLE climate." (введите имя схемы climate)
  5. искать on " заменить на on climate." (вставьте имя схемы climate)
  6. пресс F5 для выполнения

в результате:

Query returned successfully with no result in 122 ms.

ответы джедаев

в этот момент я в тупике.

  • куда мне идти отсюда (какие шаги) для преобразования climate-my.sql to climate-pg.sql чтобы они могли быть выполнены против PostgreSQL?
  • как убедиться, что индексы скопированы правильно (для поддержания ссылочной целостности; у меня нет ограничения на данный момент, чтобы облегчить переход)?
  • как я могу гарантировать, что добавление новых строк в PostgreSQL начнет перечисление из индекса последней вставленной строки (и не конфликтует с существующим первичным ключом из последовательности)?
  • как вы обеспечиваете, чтобы имя схемы проходило при преобразовании данных из MySQL в вставки PostgreSQL?

ресурсы

справедливый бит информации был необходим, чтобы получить это далеко:

спасибо ты!

4 ответов


то, что я обычно делаю для таких миграций, является двукратным:

  • извлеките все определение базы данных из MySQL и адаптируйте его к синтаксису PostgreSQL.
  • перейдите к определению базы данных и преобразуйте его, чтобы воспользоваться функциональностью в PostgreSQL, которая не существует в MySQL.

затем выполните преобразование и напишите программу на любом языке, который вам наиболее удобен, которая выполняет следующее:

  • читает данные из базы данных MySQL.
  • выполняет любое преобразование, необходимое для данных, которые будут храниться в базе данных PostgreSQL.
  • сохраняет преобразованные данные в базе данных PostgreSQL.

перепроектировать таблицы для PostgreSQL, чтобы воспользоваться его функциями.

Если вы просто делаете что-то вроде использования sed скрипт для преобразования дампа SQL из одного формата в другой, все, что вы делаете, это помещаете MySQL база данных на сервере PostgreSQL. Вы можете это сделать, и это все равно принесет некоторую пользу, но если вы собираетесь мигрировать, мигрируйте полностью.

это потребует немного больше времени, но я еще не сталкивался с ситуацией, когда это не стоит того.


конвертируйте файл mysqldump в формат PostgreSQL

преобразовать данные следующим образом (не используйте mysql2pgsql.на Perl):

  1. побег кавычек.

    sed "s/\\'/\'\'/g" climate-my.sql | sed "s/\\r/\r/g" | sed "s/\\n/\n/g" > escaped-my.sql

  2. заменить USE "climate"; С путем поиска и комментарием комментариев:

    sed "s/USE \"climate\";/SET search_path TO climate;/g" escaped-my.sql | sed "s/^\/\*/--/" > climate-pg.sql

  3. подключиться к база данных.

    sudo su - postgres
    psql climate

  4. установите кодировку (mysqldump игнорирует ее параметр кодировки), а затем выполните сценарий.

    \encoding iso-8859-1
    \i climate-pg.sql

эта серия шагов, вероятно, не будет работать для сложных баз данных со многими смешанными типами. Тем не менее, он работает для integers,varcharS и floats.

индексы, первичные ключи и последовательности

С 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()