Перейти к основному содержимому

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

· 8 мин. чтения

1. Введение

В этом руководстве мы рассмотрим ключевые концепции Flyway и то, как мы можем использовать эту структуру для надежного и простого непрерывного изменения схемы базы данных нашего приложения. Кроме того, мы представим пример управления базой данных H2 в памяти с помощью подключаемого модуля Maven Flyway.

Flyway обновляет базу данных с одной версии на другую с помощью миграции. Мы можем писать миграции либо на SQL с синтаксисом, специфичным для базы данных, либо на Java для расширенных преобразований базы данных.

Миграции могут быть версионными или повторяемыми. Первый имеет уникальную версию и применяется ровно один раз. Последний не имеет версии. Вместо этого они (повторно) применяются каждый раз, когда изменяется их контрольная сумма.

В рамках одного прогона миграции повторяемые миграции всегда применяются последними после выполнения ожидающих версий миграций. Повторяемые миграции применяются в порядке их описания. Для одной миграции все операторы выполняются в рамках одной транзакции базы данных.

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

2. Плагин Flyway Maven

Чтобы установить плагин Flyway Maven, давайте добавим следующее определение плагина в наш pom.xml:

<plugin>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-maven-plugin</artifactId>
<version>8.0.0</version>
</plugin>

Последняя версия плагина доступна на Maven Central .

Мы можем настроить этот плагин Maven четырьмя различными способами. В следующих разделах мы рассмотрим каждый из этих вариантов.

Пожалуйста, обратитесь к документации , чтобы получить список всех настраиваемых свойств.

2.1. Конфигурация плагина

Мы можем настроить плагин напрямую с помощью тега <configuration> в определении плагина нашего pom.xml:

<plugin>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-maven-plugin</artifactId>
<version>8.0.0</version>
<configuration>
<user>databaseUser</user>
<password>databasePassword</password>
<schemas>
<schema>schemaName</schema>
</schemas>
...
</configuration>
</plugin>

2.2. Мейвен Свойства

Мы также можем настроить плагин, указав настраиваемые свойства в качестве свойств Maven в нашем pom:

<project>
...
<properties>
<flyway.user>databaseUser</flyway.user>
<flyway.password>databasePassword</flyway.password>
<flyway.schemas>schemaName</flyway.schemas>
...
</properties>
...
</project>

2.3. Внешний файл конфигурации

Другой вариант — указать конфигурацию плагина в отдельном файле .conf :

flyway.user=databaseUser
flyway.password=databasePassword
flyway.schemas=schemaName
...

Имя файла конфигурации по умолчанию — flyway.conf, и по умолчанию он загружает файлы конфигурации из:

  • installDir/conf/flyway.conf
  • userhome/flyway.conf
  • рабочийDir/flyway.conf

Кодировка задается свойством flyway.encoding ( по умолчанию UTF-8 ).

Если мы используем любое другое имя (например , customConfig.conf ) в качестве файла конфигурации, то мы должны указать это явно при вызове команды Maven:

$ mvn -Dflyway.configFiles=customConfig.conf

2.4. Свойства системы

Наконец, все свойства конфигурации также можно указать как системные свойства при вызове Maven в командной строке:

$ mvn -Dflyway.user=databaseUser -Dflyway.password=databasePassword 
-Dflyway.schemas=schemaName

Ниже приведен порядок приоритета, когда конфигурация указана более чем одним способом:

  1. Свойства системы
  2. Внешний файл конфигурации
  3. Свойства Maven
  4. Конфигурация плагина

3. Пример миграции

В этом разделе мы рассмотрим необходимые шаги для переноса схемы базы данных в базу данных 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 с помощью внешнего файла

Затем мы создаем myFlywayConfig.conf в $PROJECT_ROOT со следующим содержимым:

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 придерживается следующего соглашения об именах для сценариев миграции:

<префикс><версия>__<описание>.sql

Где:

  • <Prefix> — префикс по умолчанию — V , который мы можем изменить в приведенном выше файле конфигурации, используя свойство flyway.sqlMigrationPrefix .
  • <Версия> — номер версии миграции. Основные и дополнительные версии могут быть разделены символом подчеркивания . Версия миграции всегда должна начинаться с 1.
  • <Description> — текстовое описание миграции. Двойное подчеркивание отделяет описание от номеров версий.

Пример: V1_1_0__my_first_migration.sql

Итак, давайте создадим каталог db/migration в $PROJECT_ROOT со сценарием миграции с именем V1_0__create_employee_schema.sql , содержащим инструкции SQL для создания таблицы сотрудников:

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. Выполнение миграции

Затем мы вызываем следующую команду Maven из $PROJECT_ROOT для выполнения миграции базы данных:

$ mvn clean flyway:migrate -Dflyway.configFiles=myFlywayConfig.conf

Это должно привести к нашей первой успешной миграции.

Схема базы данных теперь должна выглядеть так:

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:
+----+------+-------+---------+---------------+
| id | name | email | dept_id | date_of_birth |
+----+------+-------+---------+---------------+
department:
+----+------+
| id | name |
+----+------+

Наконец, мы можем убедиться, что обе миграции действительно прошли успешно, вызвав следующую команду Maven:

$ mvn flyway:info -Dflyway.configFiles=myFlywayConfig.conf

4. Создавайте версионные миграции в IntelliJ IDEA

Написание миграций вручную занимает много времени; вместо этого мы можем генерировать их на основе наших сущностей JPA. Мы можем добиться этого, используя плагин для IntelliJ IDEA под названием JPA Buddy .

Чтобы сгенерировать дифференциальную миграцию версий, просто установите подключаемый модуль и вызовите действие из панели JPA Structure.

Мы просто выбираем, какой источник мы хотим сравнить (база данных или объекты JPA), с какой целью (база данных или моментальный снимок модели данных). Затем JPA Buddy создаст миграцию , как показано на анимации:

./841081f24d51d54275130679a0f9445a.gif

Еще одним преимуществом JPA Buddy является возможность определять сопоставления между типами Java и баз данных. Кроме того, он корректно работает с пользовательскими типами Hibernate и конвертерами JPA.

5. Отключение Flyway в Spring Boot

Иногда нам может понадобиться отключить миграцию Flyway при определенных обстоятельствах .

Например, обычной практикой является создание схемы базы данных на основе сущностей во время тестов. В такой ситуации мы можем отключить Flyway под тестовым профилем.

Давайте посмотрим, насколько это просто в Spring Boot .

5.1. Весенняя загрузка 1.x

Все, что нам нужно сделать, это установить свойство flyway.enabled в нашем файле application-test.properties :

flyway.enabled=false

5.2. Весенняя загрузка 2.x

В более поздних версиях Spring Boot это свойство было изменено на spring.flyway.enabled :

spring.flyway.enabled=false

5.3. Empty FlywayMigrationСтратегия

Если мы хотим только отключить автоматическую миграцию Flyway при запуске, но при этом иметь возможность инициировать миграцию вручную , то использование описанных выше свойств не является хорошим выбором.

Это потому, что в такой ситуации Spring Boot больше не будет автоматически настраивать bean- компонент 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();
}
}

6. Как работает пролетный путь

Чтобы отслеживать, какие миграции мы уже применили и когда, он добавляет в нашу схему специальную учетную таблицу. Эта таблица метаданных также отслеживает контрольные суммы миграции и ее успешность.

Платформа выполняет следующие шаги, чтобы приспособиться к меняющимся схемам базы данных:

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

7. Команды

Flyway поддерживает следующие основные команды для управления миграцией базы данных:

  • Информация : выводит текущий статус/версию схемы базы данных. Он печатает, какие миграции ожидаются, какие миграции были применены, статус примененных миграций и когда они были применены.
  • Migrate : переносит схему базы данных в текущую версию. Он сканирует путь к классам на наличие доступных миграций и применяет ожидающие миграции.
  • Базовый уровень : базовый уровень существующей базы данных, исключая все миграции, включая baselineVersion . Baseline помогает начать работу с Flyway в существующей базе данных. После этого новые миграции можно применять в обычном режиме.
  • Validate : проверяет текущую схему базы данных на соответствие доступным миграциям.
  • Repair : Восстанавливает таблицу метаданных.
  • Очистить : удаляет все объекты в настроенной схеме. Конечно, мы никогда не должны использовать clean в какой-либо производственной базе данных.

8. Заключение

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

Код, сопровождающий эту статью, доступен на GitHub .