1. Введение
В этой статье описываются ключевые концепции Flyway и пример использования этого фреймворка для непрерывного изменения схемы базы данных на примере in-memory базы данных H2 с помощью maven-плагина flyway.
Flyway обновляет версии баз данных с помощью миграций. Миграции можно писать на SQL (с синтаксисом, специфичным для конкретной СУБД) или на Java.
Миграции могут быть версионными или повторяющимися. Первые имеют уникальную версию и применяются ровно один раз. У вторых номера версии нет, и они применяются, когда у них изменяется контрольная сумма.
Повторяющиеся миграции в рамках одного запуска всегда применяются после выполнения версионных миграций. Повторяющиеся миграции применяются в порядке их описания. В одной миграции все операции выполняются в рамках одной транзакции базы данных.
В этой статье мы сосредоточим внимание на использовании maven-плагина для миграций базы данных.
2. Flyway maven plugin
Добавим flyway maven plugin в
pom.xml
:
<plugin> <groupId>org.flywaydb</groupId> <artifactId>flyway-maven-plugin</artifactId> <version>4.0.3</version></plugin>
Актуальную версию плагина можно посмотреть в Maven Central.
Список параметров плагина, можно посмотреть в документации. Параметры плагина можно настроить четырьмя различными способами.
2.1. Раздел
<configuration>
плагинаПараметры можно указать напрямую в теге в разделе плагина в
pom.xml
:org.flywaydb
flyway-maven-plugin
4.0.3
databaseUser
databasePassword
schemaName
2.2. Maven properties
Также плагин можно настроить, указав параметры в
<
properties>
:
<project> ... <properties> <flyway.user>databaseUser</flyway.user> <flyway.password>databasePassword</flyway.password> <flyway.schemas>schemaName</flyway.schemas> ... </properties> ...</project>
2.3. Внешний файл конфигурации
Или описать конфигурацию в отдельном
.properties
-файле:
flyway.user=databaseUserflyway.password=databasePasswordflyway.schemas=schemaName...
По умолчанию имя файла конфигурации
flyway.properties
.
Этот файл должен находиться в том же каталоге, что и файл
pom.xml
. Кодировка задается в параметре
flyway.encoding
(по умолчанию UTF-8).Если для файла вы используете другое имя (например,
customConfig.properties
), то его нужно указать явно
при вызове maven:
$ mvn -Dflyway.configFile=customConfig.properties
2.4. System Properties
И наконец, параметры могут быть указаны как system properties при вызове maven из командной строки:
$ mvn -Dflyway.user=databaseUser -Dflyway.password=databasePassword -Dflyway.schemas=schemaName
Если конфигурация указана несколькими способами, то приоритет будет следующий:
- System properties
- Внешний файл конфигурации
- Раздел
<
properties>
- Раздел
<
configuration>
плагина
3. Пример миграции
В этом разделе мы рассмотрим необходимые шаги для миграции схемы базы данных на примере in-memory базы данных H2 с помощью maven-плагина. Для конфигурации Flyway мы будем использовать внешний файл.
3.1. Изменения в POM
Для начала, добавим зависимость на H2:
<dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <version>1.4.196</version></dependency>
Здесь мы также можем проверить последнюю доступную версию драйвера в Maven Central. Плагин для Flyway добавляем, как было описано ранее.
3.2. Настройка Flyway во внешнем файле
Создаем в
$PROJECT_ROOT
файл
myFlywayConfig.properties
со следующим содержимым:
flyway.user=databaseUserflyway.password=databasePasswordflyway.schemas=app-dbflyway.url=jdbc:h2:mem:DATABASEflyway.locations=filesystem:db/migration
Приведенная выше конфигурация указывает, что скрипты миграции находятся в каталоге
db/migration
, а для подключения к
базе данных H2 используются databaseUser
и
databasePassword
.Схема базы данных для приложения
app-db
.Конечно, в параметрах
flyway.user
,
flyway.password
и flyway.url
необходимо
указать имя, пароль и URL вашей базы данных.3.3. Первая миграция
По соглашениям Flyway имена скриптов миграции должны быть в следующем формате:
<Prefix><
Version>__<
Description>.sql
Где:
-
<
Prefix> префикс. Для версионных миграций по умолчанию равен V. Префикс настраивается через свойство flyway.sqlMigrationPrefix. -
<
Version> номер версии миграции. Мажорную и минорную версии можно разделить подчеркиванием. Версия всегда должна начинаться с 1. -
<
Description> текстовое описание миграции. Описание должно быть отделено от номера версии двумя подчеркиваниями.
Пример:
V1_1_0__my_first_migration.sql
Итак, давайте создадим каталог
db/migration
в
$PROJECT_ROOT
со скриптом миграции
V1_0__create_employee_schema.sql
и SQL для создания
таблицы employee
:
CREATE TABLE IF NOT EXISTS `employee` ( `id` int NOT NULL AUTO_INCREMENT PRIMARY KEY, `name` varchar(20), `email` varchar(50), `date_of_birth` timestamp )ENGINE=InnoDB DEFAULT CHARSET=UTF8;
3.4. Выполняем миграции
Далее, в
$PROJECT_ROOT
запускаем следующую команду
maven для применения миграций базы данных:
$ mvn clean flyway:migrate -Dflyway.configFile=myFlywayConfig.properties
Должна выполниться наша первая миграция.
Теперь схема базы данных выглядит следующим образом:
employee:
+----+------+-------+---------------+| id | name | email | date_of_birth |+----+------+-------+---------------+
Мы можем повторить предыдущие шаги для выполнения других миграций.
3.5. Вторая миграция
Для второй миграции создаем файл с именем
V2_0_create_department_schema.sql
, содержащий
следующие два запроса:
CREATE TABLE IF NOT EXISTS `department` ( `id` int NOT NULL AUTO_INCREMENT PRIMARY KEY,`name` varchar(20) )ENGINE=InnoDB DEFAULT CHARSET=UTF8; ALTER TABLE `employee` ADD `dept_id` int AFTER `email`;
Выполним миграцию, также как делали для первой миграции.
Теперь схема нашей базы данных изменилась: в
employee
добавлен новый столбец и создана новая таблица
department
:employee:
+----+------+-------+---------+---------------+| id | name | email | dept_id | date_of_birth |+----+------+-------+---------+---------------+
department:
+----+------+| id | name |+----+------+
Для проверки, что обе миграции прошли успешно, запустим следующую команду maven:
$ mvn flyway:info
-Dflyway.configFile=myFlywayConfig.properties
4. Отключение Flyway в Spring Boot
Иногда может потребоваться отключить Flyway-миграции.
Это может понадобиться во время тестов, когда схема базы данных генерируется на основе сущностей. В этом случае можно отключить Flyway для тестового профиля.
В Spring Boot это сделать очень просто.
4.1. Spring Boot 1.x
Все, что нам нужно сделать, это установить свойство
flyway.enabled
в файле
application-test.properties
:
flyway.enabled=false
4.2. Spring Boot 2.x
В более поздних версиях Spring Boot это свойство было изменено на
spring.flyway.enabled:spring.flyway.enabled=false
4.3 Пустая FlywayMigrationStrategy
Если мы хотим отключить только автоматическую миграцию Flyway при запуске, но хотим запускать миграции вручную, то использование вышеописанных свойств нам не подойдет.
Это связано с тем, что Spring Boot не будет автоматически конфигурировать бины Flyway и, следовательно, нам придется настраивать их самостоятельно, что не очень удобно.
В этом случае мы можем оставить Flyway включенным и реализовать пустую FlywayMigrationStrategy:
@Configurationpublic class EmptyMigrationStrategyConfig { @Bean public FlywayMigrationStrategy flywayMigrationStrategy() { return flyway -> { // do nothing }; }}
Фактически это отключит Flyway-миграции при запуске приложения.
Но мы все равно можем запускать миграции вручную:
@RunWith(SpringRunner.class)@SpringBootTestpublic class ManualFlywayMigrationIntegrationTest { @Autowired private Flyway flyway; @Test public void skipAutomaticAndTriggerManualFlywayMigration() { flyway.migrate(); }}
5. Как работает Flyway
Для отслеживания когда, кем и какие миграции были применены, в схему базы данных добавляется специальная таблица с метаданными. В этой таблице также хранятся контрольные суммы миграций и информация о том успешна была миграция или нет.
Фреймворк работает следующим образом:
- Проверяет схему базы данных на наличие таблицы метаданных (по
умолчанию
SCHEMA_VERSION
). Если таблица метаданных не существует, то создает ее. - Сканирует classpath на наличие доступных миграций.
- Сравнивает миграции с таблицей метаданных. Если номер версии меньше или равен версии, помеченной как текущая, то игнорирует ее.
- Отмечает все оставшиеся миграции как ожидающие (pending). Потом сортирует их по возрастанию номеров версий и выполняет в указанном порядке.
- По мере применения миграций обновляет таблицу метаданных.
6. Команды
В Flyway есть следующие основные команды по управлению миграциями:
- Info. Отображение текущего состояния / версии схемы базы данных. Информация о том, какие миграции ожидаются, какие были применены, состояние выполненных миграций и дата их выполнения.
- Migrate. Обновление схемы базы данных до текущей версии. Сканирование classpath для поиска доступных миграций и применение ожидающих миграций.
- Baseline. Установка версии схемы базы данных, игнорируя миграции до baselineVersion включительно. Baseline помогает использовать Flyway на уже существующей базе данных. Новые миграции применяются в обычном режиме.
- Validate. Проверка текущей схемы базы данных на соответствие доступным миграциям.
- Repair. Восстановление таблицы метаданных.
- Clean. Удаление всех объектов в схеме. Конечно, никогда не нужно использовать clean в продакшен базах данных.
7. Заключение
- В этой статье мы показали, как работает Flyway и как его можно использовать для надежного и простого управления изменениями базы данных.
- Код статьи доступен на GitHub.
УПРАВЛЯЕМ ВЕРСИЯМИ БАЗ ДАННХ ЧЕРЕЗ FLYWAY