Для того, чтобы 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 |
- Добавлять миграции-патчи, а затем периодических их группировать в один файл для каждой версии. Ниже пример такого процесса:
- Велась активная разработка:
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
- Функциональности стабилизировали:
001_02_initial_migration.sql
002_01_add_user.sql
003_04_add_orders.sql
- Продолжили разработку
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
.
Миграции разбиты на директории для простоты и удобства поддержки. Каждой директории соответствует отдельная таблица в базе со списком примененных миграций. Применение миграций вверх производится последовательно для всего сета миграций: от первой директории в списке до последней. Применение миграций вниз производится последовательно, но в обратном порядке для всего сета миграций: от последней директории в списке до первой.
Основная мотивация разбиения — разные сущности базы поддерживаются по-разному.
Чтобы изменить DDL таблицы, используется ALTER
statement,
а для изменения VIEW
, MATERIALIZED VIEW
, FUNCTION
и PROCEDURE
необходимо их полностью переопределить.
Это приводит к необходимости копирования всего определения в новый файл миграции и изменения уже его.
В результате мы получаем много файлов миграций с декларациями одной и той же сущности, но разных версий.
Ещё одна причина — на сложных проектах при старом подходе невозможно было удобно работать относительно объемным кол-во логики вынесенной в процедуры и функции базы данных.
- Миграции схемы данных (таблиц) вынесены отдельно и фактически с ними можно работать как раньше.
VIEW
,MATERIALIZED VIEW
,FUNCTION
иPROCEDURE
- разбиты на директории. Каждый отдельный файл миграции — это отдельная сущность.FUNCTION
иPROCEDURE
могут быть сгруппированы по их функционалу, подобно пакетам Go. Это упрощает навигацию и взаимодействие с ними.- Чтобы сделать изменения существующих
VIEW
,MATERIALIZED VIEW
,FUNCTION
илиPROCEDURE
необходимо:- изменить соответствующую декларацию в файле миграции;
- обновить имя измененного файла, а именно увеличить
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;
$$;