pgmig
Разработка и сопровождение приложений в СУБД postgresql
1. Переводы
Этот сайт доступен на следующих языках:
- Английский (черновик)
- Русский (до релиза 1.0 - наиболее полное описание)
2. Описание
pgmig - это утилита и библиотека для загрузки в БД postgresql файлов *.sql из клонированного git-репозитория (или нескольких) и последующей загрузки изменений этих файлов.
В проекте реализовано два способа изменения (миграции) БД:
- Загрузка только файлов с идемпотентными запросами (например,
CREATE OR REPLACE FUNCTION
при отсутствии изменений в сигнатуре) - Загрузка всех файлов схемы БД с ее предварительным удалением
Проект решает следующие задачи:
- Синхронизировать исходники в git и содержимое БД в части, которая не меняется в процессе эксплуатации (структура данных, представления, индексы, функции, триггеры, справочники и т.п.)
- Реализовать механизм тестирования хранимого кода
- Изменять БД только при успешном прохождении тестов
Для решения этих задач приняты следующие правила:
- Все, что загружается в БД, разбито на пакеты (схемы)
- Все, что меняется в процессе эксплуатации приложения, выносится в отдельные схемы БД (далее - оперативные данные)
- Чтобы гарантировать соответствие кода в git схемам неоперативных данных, перед обновлением они удаляются
- Весь SQL-код разделяется на файлы так, чтобы любое изменение БД можно было описать маской имен файлов, которые должны быть для него выполнены
2.1. Состав проекта
- pgmig - встраиваемая библиотека и утилита для миграции (golang)
- pgmig.perl - порт pgmig на perl
- SQL-пакеты:
3. Технические детали
3.1. Архитектура решения
Исходим из того, что есть некое приложение, использующее БД и в этой БД есть информация 2х типов:
- оперативные данные, которые появляются в результате действий пользователей или администраторов приложения
- все остальное, что является результатом работы программистов (и должно храниться в git)
Решение может быть в том, чтобы первое положить в отдельные схемы БД, а схемы из п.2 при обновлении БД можно было удалять.
Связи между этими схемами, которые надо учитывать:
- Внешние ключи (некоторые справочники меняют только программисты, на них завязан код)
- Функции, которые возвращают значение по умолчанию
Эти связи регистрируются в специальных таблицах, что позволяет удалять их вместе с пакетами, восстанавливать при создании и все это производить в одной транзакции.
3.2. Порядок работы
Работа мигратора заключается в последовательном выполнении файлов, соответствующих маске, из заданных каталогов.
Формат вызова:
pgmig [options] init|test|drop|erase|reinit dir1[ dir2]...
Для каждой команды задан список масок файлов:
Команда | Маска | Назначение |
---|---|---|
init | *.sql | Создание схемы и объектов БД |
test | *.test.sql | Тесты для выполнения в init и отдельно |
Команды, которые используют загруженный ранее код
Команда | Функция | Назначение |
---|---|---|
drop | cleanup() | удаление связей текущей схемы с другими схемами, удаление схемы пакета (если такой функции нет, схема БД будет удалена при вызове pkg_op_after() ) |
erase | cleanup(true) | drop + удаление защищенных объектов из других схем (персистентных данных) |
Команда reinit
представляет собой последовательное выполнение drop
, init
в одной транзакции.
Команда update
(TODO) аналогична init
, но пропускаются пакеты с версией, совпадающей с уже загруженной в БД.
При выполнении init
используются дополнительные группы файлов:
Группа | Маска | Назначение |
---|---|---|
new | *.new.sql | не выполняется, если пакет был создан ранее |
once | *.once.sql | файл не выполняется повторно, пока не выполнен erase (если нет таких файлов, не будет проверки вызовом script_protected) |
Сервисные функции SQL
Вызывает pgmig
pkg_version(pkg)
- проверка существования пакета в БДpkg_op_before(op, pkg, version, repo)
- операции перед выполнением заданной команды (для каждого пакета)pkg_op_after(op, pkg, version, repo)
- операции после выполнения заданной команды (для каждого пакета)script_protected(pkg,file)
- проверка регистрации файла однократного запускаscript_protect(pkg,file,csum)
- регистрация файла однократного запуска и его контрольной суммы
Используются в sql
comment(type,code,comment...)
- создание комментария к объекту БДassert_count(cnt)
- указание количества тестов в текущем файлеassert_eq()
- тест - проверка на совпадение значений
Регистрация связей производится в файлах группы once при выполнении команды init.
Пример разделения файлов по префиксу
Префикс | Имя | Описание |
---|---|---|
0x | init | инициализация, проверка зависимостей от других пакетов |
1x | common | функции, не имеющие зависимостей от объектов схемы |
2x | table.once | создание таблиц в персистентных схемах (повторный вызов будет только после erase) |
2x | table.new | создание таблиц и типов |
3x | view | представления и функции для них |
4x | func | основной код функций |
4x | func.test | тесты функций |
5x | trig | код триггеров |
6x | trig.new | создание триггеров |
7x | data.new | наполнение таблиц |
Далее: В разработке
4. История
- Первая версия этой техники была реализована в 2010 как часть проекта PgWS
- Второе поколение - pomasql
- Эта документация описывает третье поколение
5. Авторы
- Алексей Коврижкин - Идея и первичная реализация - LeKovr
См. Также список контрибьюторов, которые принимали участие в проекте.
6. Лицензия
Исходный код проектов pgmig публикуется под лицензией Apache 2.0 - см файл LICENSE.md.