Миграция базы данных

Миграция схемы базы данных, или сокращенно миграция базы данных, – это процесс обновления схемы базы данных в соответствии с изменениями модели данных приложения.

Jmix использует Liquibase в качестве инструмента миграции базы данных.

Процесс

Jmix Studio создает скрипты миграции в формате Liquibase changelog, сравнивая текущее состояние сущностей JPA с текущей схемой базы данных соответствующего хранилища данных. Это происходит автоматически при запуске приложения с использованием конфигурации Run/Debug. Файл changelog сохраняется в исходном коде приложения и собирается в составе бинарного артефакта.

Генерацию Liquibase changelog можно отключить, открыв на редактирование Run/Debug configuration и удалив шаг Check Jmix Database, выполняющийся перед запуском.

Когда приложение запускается, оно автоматически запускает Liquibase со сгенерированными changelog для обновления подключенной базы данных.

Вы также можете в любое время создать changelog с помощью действия Generate Diff Changelog и выполнить его с помощью действия Update в хранилище данных в окне инструментов Studio Jmix.

Модули, от которых зависит ваше приложение, также могут содержать файлы Liquibase changelog. Файлы changelog из зависимостей выполняются в базе данных раньше, чем в приложении.

Структура файлов changelog

Studio генерирует файлы changelog в каталоге src/main/resources/<base_package>/liquibase проекта приложения. Там Studio создает каталог changelog для основного хранилища данных и каталоги <store>-changelog для дополнительных хранилищ данных. Файлы changelog создаются в подкаталогах, соответствующих году и месяцу текущей даты. Имя каждого файла включает текущий день, порядковый номер в течение дня и случайную последовательность символов, чтобы избежать конфликтов, если несколько разработчиков работают над одним и тем же проектом.

Для каждого хранилища данных существует основной файл changelog, расположенный в каталоге src/main/resources/<base_package>/liquibase. Он содержит директиву для включения всех сгенерированных файлов changelog в подкаталог changelog. Мастер-файл changelog передается в Liquibase, когда приложение или Studio запускают миграцию базы данных.

src/main/resources/datamodel/ex1/
├── liquibase/ (1)
│   ├── changelog/ (2)
│   │   ├── 010-init-user.xml (3)
│   │   └── 2020/
│   │       ├── 11/
│   │       │   ├── 12-010-fe2b82e6.xml (4)
│   │       │   └── 27-010-fe2b82e6.xml
│   │       └── 12/
│   │           └── 17-010-fe2b82e6.xml
│   ├── changelog.xml (5)
│   ├── locations-changelog/ (6)
│   │   └── 2020/
│   │       └── 11/
│   │           ├── 25-010-fe2b82e6.xml
│   │           └── 28-010-fe2b82e6.xml
│   └── locations-changelog.xml (7)
1 Корень структуры файлов changelog Liquibase.
2 Каталог файлов changelog основного хранилища данных.
3 Файл changelog, предоставляемый в новом проекте. Он создает таблицу для сущности User.
4 Файлы changelog, которые генерирует Studio.
5 Мастер-файл changelog основного хранилища данных.
6 Каталог файлов changelog хранилища данных locations.
7 Мастер-файл changelog хранилища данных locations.

Вы можете написать файлы changelog Liquibase вручную и поместить их в структуру, описанную выше. Liquibase выполняет включенные файлы changelog в алфавитном порядке, учитывая их полный путь, поэтому давайте файлам соответствующие имена.

Никогда не удаляйте мастер-файл changelog.xml, так как он требуется для запуска процесса миграции. Кроме того, не удаляйте файл changelog/010-init-user.xml если не собираетесь реализовывать нестандартную систему безопасности.

Настройка Liquibase

Вы можете настроить свойства Liquibase для основного хранилища данных в application.properties таким же образом, как описано в документации Spring Boot (см. свойства spring.liquibase.*), но заменяя префикс spring.liquibase на jmix.liquibase, например:

jmix.liquibase.enabled = false
Вы не можете изменить свойство change-log, потому что фреймворк всегда устанавливает в него мастер-файл changelog.

По умолчанию, Jmix Studio сравнивает с моделью данных все таблицы базы данных, и генерирует скрипты миграции, включающие команды DROP TABLE для таблиц, не отображенных на сущности. Если в вашей базе данных есть таблицы, не связанные с сущностями приложения, вы можете проигнорировать их, указав их префиксы или имена целиком через запятую в свойстве main.datasource.studio.liquibase.excludePrefixes. Например:

main.datasource.studio.liquibase.excludePrefixes = abc_,foo,bar

Для дополнительного хранилища данных, замените main в имени свойства именем этого хранилища.

Если вы хотите экстернализировать Liquibase свойства дополнительного хранилища данных, поменяйте его настройки, как показано в следующем примере:

@Bean
@ConfigurationProperties(prefix = "locations.liquibase")
public LiquibaseProperties locationsLiquibaseProperties() {
    return new LiquibaseProperties();
}

@Bean
public SpringLiquibase locationsLiquibase(LiquibaseChangeLogProcessor processor) {
    return JmixLiquibaseCreator.create(locationsDataSource(),
            locationsLiquibaseProperties(), processor, "locations");
}

В результате вы сможете задать Liquibase свойства хранилища данных locations в application.properties с помощью префикса locations.liquibase.