Перейти к содержанию

Выполнение произвольных скрптов при обновлении БД#

Стандартного механизма обновления БД не всегда достаточно, когда речь идет о наполнении справочников или сложных изменениях в структуре БД. Для таких задач была добавлена возможность выполнения произвольных скриптов, позволяющая гибко управлять состоянием базы.

Создание файлов миграции#

Для реализации кастомной логики обновления необходимо создать объект миграции в директории sqlScripts. Эта папка должна находиться в корне исходников прикладной библиотеки или проекта (по умолчанию — папка source). Поддерживается использование вложенных папок для структуризации.

Структура объекта миграции#

Объект миграции всегда состоит из двух файлов: файла описания и SQL-скрипта.

  1. Файл описания - содержит метаданные и настройки запуска. Должен иметь расширение .migration.json.
  2. SQL-скрипт - содержит непосредственно логику миграции. Должен иметь расширение .sql.

Предупреждение

Путь к файлу описания используется как уникальный идентификатор обновления. Не переименовывайте файл и не изменяйте его путь после выполнения миграции, иначе система посчитает его новым и запустит скрипт повторно.

Формат файла описания#

Пример содержимого файла example.migration.json:

1
2
3
4
5
6
{
    "description": "Перенос данных в таблицу справочника",
    "executionPolicy": "onChange",
    "script": "./transferData.sql",
    "priority": 100
}
  • description - текст описания миграции (будет отображаться в интерфейсе обновления БД).
  • executionPolicy - определяет сбособ выполнения скрипта:
    • onChange - скрипт выполнится, если он еще не запускался, либо если в содержимое SQL-файла были внесены изменения.
    • once - скрипт выполнится один раз.
    • always - скрипт будет выполняться при каждом запуске обновления.
  • script - относительный путь к SQL-файлу с логикой миграции.
  • priority - приоритет выполнения. Чем меньше число, тем раньше выполнится скрипт. По умолчанию 100.

Пример sql-файла ./transferData.sql:

1
2
3
4
5
6
7
8
-- Пример для PostgreSQL: добавление записей, если их еще нет
INSERT INTO public."OrderStatuses" (id, name, code)
SELECT 1, 'Новый', 'NEW'
WHERE NOT EXISTS (SELECT 1 FROM public."OrderStatuses" WHERE code = 'NEW');

INSERT INTO public."OrderStatuses" (id, name, code)
SELECT 2, 'В работе', 'IN_PROGRESS'
WHERE NOT EXISTS (SELECT 1 FROM public."OrderStatuses" WHERE code = 'IN_PROGRESS');

Подключение файлов миграции из прикладных библиотек#

Если вы устанавливаете прикладные бибилотеки, которые содержат собственные произвольные миграции, их необходимо подключить в файле внешних зависимостей external-manual.json. В разделе sqlScripts необходимо указать пути к файлам описания миграций из соответствующих пакетов.

Пример файла external-manual.json:

1
2
3
4
5
6
7
{
  "include": {
    "sqlScripts": [
      "ecosoft-lexema8-test/lib/sqlScripts/**/*.migration.json"
    ]
  }
}

Важные особенности#

  1. Учитывайте, что миграция может запускаться в двух разных сценариях:
    • На новом проекте: где структура БД создается с нуля.
    • На существующем проекте: где база уже наполнена данными и имеет определенную структуру.

Ваш скрипт должен корректно отрабатывать в обоих случаях.

  1. Пишите скрипты так, чтобы их многократный запуск не приводил к ошибкам. Это особенно важно для политики onChange. Примеры:
    • при изменении типа колонки проверяйте текущее состояние через системные таблицы.
    • при заполнении справочников используйте конструкции, предотвращающие дублирование.
  2. Система не оборачивает выполнение скриптов в транзакцию автоматически. Если логика миграции требует атомарности (выполнения всех команд как единого целого), необходимо самостоятельно прописывать операторы транзакций (BEGIN TRANSACTION, COMMIT, ROLLBACK) внутри вашего SQL-скрипта.

Выполнение скриптов#

Скрипты выполняются на форме обновления БД /dev#/view/migration