Skip to content

Instantly share code, notes, and snippets.

@sheb-gregor
Created May 26, 2020 13:17
Show Gist options
  • Save sheb-gregor/50a9a1a4ed77ec1d595858c88f2219d2 to your computer and use it in GitHub Desktop.
Save sheb-gregor/50a9a1a4ed77ec1d595858c88f2219d2 to your computer and use it in GitHub Desktop.
How to deal with patchable multi-migrations?

How to deal with patchable multi-migrations?

Migrations with Patch

Для того, чтобы patchable migrations работали необходимо, чтобы имя файла миграции соответствовало шаблону: version_patch_some_readable_name.sql. Например: 007_04_deposit_withdrawals.sql. Так же в настройках мигратора должен быть включен PatchMode (флаг EnablePatchMode).

Миграции с PatchMode обрабатываются следующим образом — применяются все миграции от меньшей версии к больше, перед переходом к следующей версии, будут применены все патчи для текущей версии.

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

При откатывании миграции порядок от большей версии к меньшей, для каждой версии откатываются патчи начиная с последнего.

Список патчей не хранится. Сохраняется только имя самой первой версии данной миграции, её версия и последний патч.

Вот пример таблицы миграций:

ver patch name created_at updated_at
001 00 001_00_price_storage.sql 2020-05-26 08:20:41.888550 2020-05-26 08:20:41.888551
002 00 002_00_users.sql 2020-05-26 08:20:41.906273 2020-05-26 08:20:41.906273
003 00 003_00_funds.sql 2020-05-26 08:20:41.918437 2020-05-26 08:20:41.918437
004 00 004_00_btc_transactions.sql 2020-05-26 08:20:41.939334 2020-05-26 08:20:41.939334
005 00 005_00_eth_transactions.sql 2020-05-26 08:20:41.959316 2020-05-26 08:20:41.959316
006 00 006_00_xrp_transactions.sql 2020-05-26 08:20:41.969938 2020-05-26 08:20:41.969938
007 00 007_00_deposit_withdrawals.sql 2020-05-26 08:20:41.975421 2020-05-26 08:20:41.975421
008 01 008_00_trading.sql 2020-05-26 08:20:42.021335 2020-05-26 08:20:42.030642
009 00 009_00_referral_program.sql 2020-05-26 08:20:42.043198 2020-05-26 08:20:42.043198
010 00 010_00_bots.sql 2020-05-26 08:20:42.053911 2020-05-26 08:20:42.053911

Как можно работать с патчами

  • Добавлять миграции-патчи, а затем периодических их группировать в один файл для каждой версии. Ниже пример такого процесса:
  1. Велась активная разработка:
001_00_initial_migration.sql
001_01_patch_first.sql
001_02_patch_second.sql
002_00_add_user.sql
002_01_fix_user.sql
003_00_add_orders.sql
003_01_fix_orders.sql
003_02_fix_orders.sql
003_03_fix_orders.sql
003_04_fix_orders.sql
  1. Функциональности стабилизировали:
001_02_initial_migration.sql
002_01_add_user.sql
003_04_add_orders.sql
  1. Продолжили разработку
001_02_initial_migration.sql
002_01_add_user.sql
003_04_add_orders.sql
003_05_alter_orders.sql
004_00_add_statistic.sql
005_00_add_smt.sql
  • Изменить содержимое миграции и затем увеличить patch-number на единицу в названии файла. Такой подход наиболее актуален для миграций содержащих VIEW, MATERIALIZED VIEW, FUNCTION или PROCEDURE.

Migrations Set

Миграции разбиты на директории для простоты и удобства поддержки. Каждой директории соответствует отдельная таблица в базе со списком примененных миграций. Применение миграций вверх производится последовательно для всего сета миграций: от первой директории в списке до последней. Применение миграций вниз производится последовательно, но в обратном порядке для всего сета миграций: от последней директории в списке до первой.

Основная мотивация разбиения — разные сущности базы поддерживаются по-разному.

Чтобы изменить DDL таблицы, используется ALTER statement, а для изменения VIEW, MATERIALIZED VIEW, FUNCTION и PROCEDURE необходимо их полностью переопределить.

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

Ещё одна причина — на сложных проектах при старом подходе невозможно было удобно работать относительно объемным кол-во логики вынесенной в процедуры и функции базы данных.

Что даёт новый подход?

  1. Миграции схемы данных (таблиц) вынесены отдельно и фактически с ними можно работать как раньше.
  2. VIEW, MATERIALIZED VIEW, FUNCTION и PROCEDURE - разбиты на директории. Каждый отдельный файл миграции — это отдельная сущность.
  3. FUNCTION и PROCEDURE могут быть сгруппированы по их функционалу, подобно пакетам Go. Это упрощает навигацию и взаимодействие с ними.
  4. Чтобы сделать изменения существующих VIEW, MATERIALIZED VIEW, FUNCTION или PROCEDURE необходимо:
    1. изменить соответствующую декларацию в файле миграции;
    2. обновить имя измененного файла, а именно увеличить patch-number на единицу.

ВАЖНО!

Такие миграции обязательно должны предусматривать наличие сущности в базе. Обязательно необходимо использовать подход либо CREATE OR REPLACE, либо DROP ... IF EXISTS ...; CREATE ....

Например:

DROP VIEW IF EXISTS vw_traders_followers;
CREATE VIEW vw_traders_followers(trader_id, count) AS
SELECT following.trader_user_uid AS trader_id,
       count(*)                  AS count
FROM following
GROUP BY following.trader_user_uid;
CREATE OR REPLACE FUNCTION public.min_dp(v1 DOUBLE PRECISION, v2 DOUBLE PRECISION) RETURNS DOUBLE PRECISION
    LANGUAGE plpgsql
AS
$$
BEGIN
    IF v1 >= v2
    THEN
        RETURN v2;
    END IF;
    IF v1 < v2
    THEN
        RETURN v1;
    END IF;
END;
$$;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment