pgmig - postgresql database migrations
pgmig - это инструмент для управления изменениями схемы БД postgresql, который добавляет изменениям следующие возможности
- изменения выполняются в одной транзакции загрузкой исходного кода из файлов в алфавитном порядке их имен
- имена файлов с хранимым кодом и его тестами имеют заданную маску и они выполняются при любом изменении
- для отката от версии Б к версии А достаточно иметь содержимое БД (версии Б) и исходники версии А
- номер версии БД определяется по git-атрибутам загружаемого исходного кода
- история изменений схемы данных и хранимого кода контролируется git
Варианты изменения схемы БД
Обновление (up)
Загрузка в БД изменений и компиляция хранимого кода.
В корневом каталоге и каждом подкаталоге, для каждого файла с маской *.sql
- если соответствует маске
--code_mask
- загрузить - иначе - проверить наличие файла в БД
- если нет - загрузить и сохранить в БД контрольную сумму
- если контрольная сумма совпадает - пропустить
- иначе - прекратить работу с ошибкой
Дополнения
- кроме контрольной суммы, для каждого файла в БД сохраняется номер текущей версии каталога (по данным git).
- корневой каталог для загружаемых файлов задается аргументом
--dir
. - подкаталоги и файлы просматриваются в алфавитном порядке
- подкаталоги и файлы, имена которых начинаются с точки, игнорируются.
- если задан аргумент
--down-delimiter
, часть файла, идущая после его значения, не выполняется, а используется как аргумент функцииpgmig.down
(для совместимости с goose)
Откат (down)
В терминах pgmig
, откат означает отмену обновлений, сделанных после текущей версии, и выполняется так:
- для всех загруженных в БД файлов с версией больше текущей (в обратном алфавитному порядке) выполнить блок отката
- по завершении обработки каталога выполнить все соответствующие ему файлы по маске
--code_mask
Блоки отката
Размещаются в .sql файлах и содержат команды, отменяющие содержащиеся в них изменения схемы БД.
Пример блока отката:
|
|
Такой вариант позволяет выполнить файл с помощью psql
без изменений.
Загрузка текущей версии (build)
Команда представляет собой обновление до текущей версии с её предварительным откатом, предназначена для поддержки процесса разработки и включает следующее:
- выполнить блоки отката для всех файлов с именем, которое в алфавитном порядке идет после заданного аргументом
--target
(по умолчанию:10_schema.sql
) - выполненить
обновление
.
Дополнения
- если версия БД новее версии файлов, выполнение завершается с ошибкой
- специальные значения аргумента
--target
last
- выполняется только блок отката последнего файлаall
- блоки отката выполняются для всех файлов в каталогеreset
- блоки отката выполняются для всех файлов в каталоге,обновление
не выполняется
Другие команды
code
- выполнить файлы, заданные--code-mask
status
- вывести реестр загруженных в БД файловversion
- вывести версию pgmig
Опции
--cmd
- команда миграции (если не задано иначе)--dir
- каталог, где лежат пакеты--pkg
- список пакетов (если не задано - совпадает со списком подкаталогов)--exclude
- список игнорируемых пакетов--code_mask
- шаблон имени файла с кодом (по умолчанию: *.code.sql)--down-delimiter
- разделитель для блока отката--target
- целевой файл отката для командыbuild
--version
- источник версии файлов в каталоге--verbose
- выводить отладочную информацию--nocommit
- не выполнять коммит по завершении (exitstatus вернет наличие ошибок)--json
- форматировать вывод как список json
Переменные
Перед загрузкой файла в БД и перед выполнением блока отката, в БД устанавливаются значения переменных, доступные через вызовы функций:
pgmig.var_file()
- имя файлаpgmig.var_path()
- путь к файлуpgmig.var_version()
- версия каталога
Дополнения
Код возврата
Миграция прерывается при одном из условий
- 01 - ошибка в параметрах конфигурации
- 02 - команда не входит в число поддерживаемых
- 03 - команда не входит в число поддерживаемых
- 04 - после обработки всех файлов каталога зафиксирована ошибка в тестах
- 05 - при обработке файла зафиксирована ошибка выполнения SQL
- 06 - попытка выполнить
build
при версии БД больше текущей
Версии БД
При выполнении миграций используется номер текущей версии. Он может быть свой для каждого каталога и определяется аргументом --version
Специальные значения аргумента --version
git
- взять версию из .gitinfo (если есть) или метаданных git-репозитория (иначе)gitinfo
- взять версию из .gitinfoprefix
- взять версию из префикса файла
Если источником задан git, номер текущей версии берется из метаданных git-репозитория, которые могут быть привязаны к текущему каталогу или его предку.
SQL-код поддержки pgmig
Дополнение БД сервисным хранимым кодом для документирования, тестов и разграничения доступа
pgmig.down
- регистрация блока откатаpgmig.extra
- регистрация запросов вне транзакций
Запросы вне транзакций
Если при выполнении миграции возникает необходимость выполнить SQL-запросы вне транзакции (например CREATE INDEX CONCURRENTLY
), код этих запросов регистрируется при обновлении вызовом pgmig.extra(sql)
и выполняется в отдельной горутине после выполнения COMMIT
.
Параллельные миграции
В текущей версии параддельные миграции не поддерживаются. В начале работы ставится эксключивный лок до завершения
Структура проекта pgmig
- / - golang-пакет для встраивания в приложения
- /cmd/pgmig - приложение для управления изменениями (docker)
- /sql - SQL-код поддержки pgmig (поддерживает встраивание как pgmig/pgmigsql)