Подтвердить что ты не робот

Перенос с MySQL на PostgreSQL на Linux (Kubuntu)

Долгое время в системе далеко, далеко...

Попытка переноса базы данных с MySQL на PostgreSQL. Вся документация, которую я прочитал, содержит подробные сведения о том, как перенести структуру. Я очень мало документировал миграцию данных. Схема имеет 13 таблиц (которые были успешно перенесены) и 9 ГБ данных.

Версия MySQL: 5.1.x
Версия PostgreSQL: 8.4.x

Я хочу использовать язык программирования R для анализа данных с помощью операторов выбора SQL; 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

Извлеките DDL, совместимый с PostgreSQL, и все данные 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 вставки?

Ресурсы

Для достижения этой цели понадобилась справедливая информация:

Спасибо!

4b9b3361

Ответ 1

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

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

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

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

Редизайн таблиц для PostgreSQL, чтобы воспользоваться его возможностями.

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

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

Ответ 2

Преобразование файла 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 игнорирует свой параметр кодирования), а затем выполните script.

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

Эта серия шагов, вероятно, не будет работать для сложных баз данных со многими смешанными типами. Однако он работает для integer s, varchar s и float s.

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

Так как mysqldump включал первичные ключи при создании операторов INSERT, они будут превзойти автоматическую последовательность таблицы. После проверки последовательности для всех таблиц остались 1.

Задайте последовательность после импорта

Использование команды ALTER SEQUENCE установит их в любое значение.

Префикс схемы

Нет необходимости префиксных таблиц с именем схемы. Использование:

SET search_path TO climate;

Ответ 3

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

  • dump schema из PostgreSQL (вы сказали, что вы преобразовали схему в postgres, поэтому сейчас мы будем ее выгружать, поскольку мы будем удалять и воссоздавать целевую базу данных, чтобы очистить ее):

    pg_dump dbname > /tmp/dbname-schema.sql
    
  • разделите схему на 2 части - /tmp/dbname-schema-1.sql, содержащие инструкции create table, /tmp/dbname-schema-2.sql - остальные. PostgreSQL необходимо импортировать данные, прежде чем импортировать внешние ключи, триггеры и т.д., Но после импорта таблиц.

  • воссоздайте базу данных только с одной частью схемы:

    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.
    
    В MySQL 5.1.3 добавлена ​​опция < <22 > , поэтому, если у вас установлена ​​более старая версия, то временно установите более новую 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
    

Ответ 4

Отъезд etlalchemy. Он позволяет вам перейти с MySQL на PostgreSQL или между несколькими другими базами данных в 4 строках Python. Вы можете прочитать об этом здесь.

Для установки: pip install etlalchemy

Для запуска:

from etlalchemy import ETLAlchemySource, ETLAlchemyTarget
# Migrate from MySQL to PostgreSQL
src = ETLAlchemySource("mysql://user:[email protected]/dbname")
tgt = ETLAlchemyTarget("postgresql://user:[email protected]/dbname",
                          drop_database=True)
tgt.addSource(src)
tgt.migrate()