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=databaseUser flyway.password=databasePassword flyway.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=databaseUser flyway.password=databasePassword flyway.schemas=app-db flyway.url=jdbc:h2:mem:DATABASE flyway.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:
@Configuration public class EmptyMigrationStrategyConfig { @Bean public FlywayMigrationStrategy flywayMigrationStrategy() { return flyway -> { // do nothing }; } }
Фактически это отключит Flyway-миграции при запуске приложения.
Но мы все равно можем запускать миграции вручную:
@RunWith(SpringRunner.class) @SpringBootTest public 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
ссылка на оригинал статьи https://habr.com/ru/company/otus/blog/506788/
Добавить комментарий