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) - выполненить
обновление.
Дополнения
- если версия БД новее версии файлов, выполнение завершается с ошибкой
- специальные значения аргумента
--targetlast- выполняется только блок отката последнего файлаall- блоки отката выполняются для всех файлов в каталогеreset- блоки отката выполняются для всех файлов в каталоге,обновлениене выполняется
Другие команды
code- выполнить файлы, заданные--code-maskstatus- вывести реестр загруженных в БД файлов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)