Возникла задача перенести работающую БД с MySQL на Postgres.

Для этого я воспользовался вот этим инструментом - pgloader

Pgloader

Сразу хочу предостеречь - возможны проблемы с неправильной конвертацией типов колонок. К примеру smallint может превратиться в boolean и т.д. Для того чтобы быть полностью уверенными что все конвертнулось правильно нужно писать отдельный конфиг для миграции. Либо перейти в конец поста и почитать про второй способ.

Так как проект работает в докере миграцию я также решил провести при помощи вспомогательных докер-контейнеров.

1) Добавил контейнер с PostgreSQL, pgloader и adminer в конфиге docker-compose.yml

  postgres:
    image: postgres
    restart: always
    environment:
      POSTGRES_DB: mydb
      POSTGRES_PASSWORD: mysuperpass
      PGDATA: /usr/lib/postgresql/data
    volumes:
      - ./db/postgres:/usr/lib/postgresql/data

# Нужно для миграции с MySQl на Postgres
#
  pgloader:
    image: dimitri/pgloader

  adminer:
    image: adminer

2) Добавил в конфиг Nginx настройку для доступности adminer. Также у контейнера с nginx открыл порт 8080

server {
    listen 8080;
    server_name _;

    location / {
        proxy_pass http://adminer:8080;
        access_log off;
    }
}

3) Все поднял и мигрировал БД вот таким нехитрым набором команд

docker-compose up -d
docker-compose run --rm  pgloader /bin/bash

pgloader mysql://root:mysuperpass@db/mydb postgresql://postgres:mysuperpass@postgres/mydb

После этого увидел таблицу с подробностями по импорту сообщающую что импорт прошел успешно.

Тут я видимо что-то напутал и в новой БД Postgres не увидел данных =) Оказалось что в базе mydb создалась новая схема mydb, а по-умолчанию схема должна называться public.

Чтобы решить этот вопрос я зашел через adminer в Postgres и выпилил в БД mydb пустую схему public, а свежесозданную схему mydb переименовал в public. После этого все заработало.

Dummy migrate

Первый способ мне не сильно помог. А эксперименты с разными ключами pgloader не увенчались успехом. Не осилил короче я его =)

Мне же нужен был самый тупой перенос с рабочей базы MySQL, на пустую Postgres-базу на которую накатили миграции. То есть надо было просто взять данные и положить в новую БД не заморачиваясь с типами полей (они уже были определены при миграции).

Для этого я набросал простой python-скрипт который сделал все что нужно.

Dummy migrate

Предыдущая запись