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

от автора

Перевод статьи подготовлен в преддверии старта курса «Разработчик Java».


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

Если конфигурация указана несколькими способами, то приоритет будет следующий:

  1. System properties
  2. Внешний файл конфигурации
  3. Раздел <properties>
  4. Раздел <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

Для отслеживания когда, кем и какие миграции были применены, в схему базы данных добавляется специальная таблица с метаданными. В этой таблице также хранятся контрольные суммы миграций и информация о том успешна была миграция или нет.

Фреймворк работает следующим образом:

  1. Проверяет схему базы данных на наличие таблицы метаданных (по умолчанию SCHEMA_VERSION). Если таблица метаданных не существует, то создает ее.
  2. Сканирует classpath на наличие доступных миграций.
  3. Сравнивает миграции с таблицей метаданных. Если номер версии меньше или равен версии, помеченной как текущая, то игнорирует ее.
  4. Отмечает все оставшиеся миграции как ожидающие (pending). Потом сортирует их по возрастанию номеров версий и выполняет в указанном порядке.
  5. По мере применения миграций обновляет таблицу метаданных.

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/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *