v0.35

pgmig

Разработка и сопровождение приложений в СУБД postgresql

1. Переводы

Этот сайт доступен на следующих языках:

  • Английский (черновик)
  • Русский (до релиза 1.0 - наиболее полное описание)

2. Описание

pgmig - это утилита и библиотека для загрузки в БД postgresql файлов *.sql из клонированного git-репозитория (или нескольких) и последующей загрузки изменений этих файлов.

В проекте реализовано два способа изменения (миграции) БД:

  1. Загрузка только файлов с идемпотентными запросами (например, CREATE OR REPLACE FUNCTION при отсутствии изменений в сигнатуре)
  2. Загрузка всех файлов схемы БД с ее предварительным удалением

Проект решает следующие задачи:

  • Синхронизировать исходники в git и содержимое БД в части, которая не меняется в процессе эксплуатации (структура данных, представления, индексы, функции, триггеры, справочники и т.п.)
  • Реализовать механизм тестирования хранимого кода
  • Изменять БД только при успешном прохождении тестов

Для решения этих задач приняты следующие правила:

  • Все, что загружается в БД, разбито на пакеты (схемы)
  • Все, что меняется в процессе эксплуатации приложения, выносится в отдельные схемы БД (далее - оперативные данные)
  • Чтобы гарантировать соответствие кода в git схемам неоперативных данных, перед обновлением они удаляются
  • Весь SQL-код разделяется на файлы так, чтобы любое изменение БД можно было описать маской имен файлов, которые должны быть для него выполнены

2.1. Состав проекта

  • pgmig - встраиваемая библиотека и утилита для миграции (golang)
  • pgmig.perl - порт pgmig на perl
  • SQL-пакеты:
    • pgmig - управление пакетами и зависимостями
    • testing-xml - поддержка тестов для функций, которые возвращают xml
    • rpc - реализация RPC для проекта apisite
    • enfist - прикладная логика проекта enfist

3. Технические детали

3.1. Архитектура решения

Исходим из того, что есть некое приложение, использующее БД и в этой БД есть информация 2х типов:

  1. оперативные данные, которые появляются в результате действий пользователей или администраторов приложения
  2. все остальное, что является результатом работы программистов (и должно храниться в git)

Решение может быть в том, чтобы первое положить в отдельные схемы БД, а схемы из п.2 при обновлении БД можно было удалять.

Связи между этими схемами, которые надо учитывать:

  1. Внешние ключи (некоторые справочники меняют только программисты, на них завязан код)
  2. Функции, которые возвращают значение по умолчанию

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

3.2. Порядок работы

Работа мигратора заключается в последовательном выполнении файлов, соответствующих маске, из заданных каталогов.
Формат вызова:

  pgmig [options] init|test|drop|erase|reinit dir1[ dir2]...

Для каждой команды задан список масок файлов:

КомандаМаскаНазначение
init*.sqlСоздание схемы и объектов БД
test*.test.sqlТесты для выполнения в init и отдельно

Команды, которые используют загруженный ранее код

КомандаФункцияНазначение
dropcleanup()удаление связей текущей схемы с другими схемами, удаление схемы пакета (если такой функции нет, схема БД будет удалена при вызове pkg_op_after())
erasecleanup(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.

Пример разделения файлов по префиксу

ПрефиксИмяОписание
0xinitинициализация, проверка зависимостей от других пакетов
1xcommonфункции, не имеющие зависимостей от объектов схемы
2xtable.onceсоздание таблиц в персистентных схемах (повторный вызов будет только после erase)
2xtable.newсоздание таблиц и типов
3xviewпредставления и функции для них
4xfuncосновной код функций
4xfunc.testтесты функций
5xtrigкод триггеров
6xtrig.newсоздание триггеров
7xdata.newнаполнение таблиц

Далее: В разработке

4. История

  • Первая версия этой техники была реализована в 2010 как часть проекта PgWS
  • Второе поколение - pomasql
  • Эта документация описывает третье поколение

5. Авторы

  • Алексей Коврижкин - Идея и первичная реализация - LeKovr

См. Также список контрибьюторов, которые принимали участие в проекте.

6. Лицензия

Исходный код проектов pgmig публикуется под лицензией Apache 2.0 - см файл LICENSE.md.