Перевод статьи подготовлен в преддверии старта курса «Разработчик Java».
В этой статье описываются ключевые концепции Flyway и пример использования этого фреймворка для непрерывного изменения схемы базы данных на примере in-memory базы данных H2 с помощью maven-плагина flyway.
Flyway обновляет версии баз данных с помощью миграций. Миграции можно писать на SQL (с синтаксисом, специфичным для конкретной СУБД) или на Java.
Миграции могут быть версионными или повторяющимися. Первые имеют уникальную версию и применяются ровно один раз. У вторых номера версии нет, и они применяются, когда у них изменяется контрольная сумма.
Повторяющиеся миграции в рамках одного запуска всегда применяются после выполнения версионных миграций. Повторяющиеся миграции применяются в порядке их описания. В одной миграции все операции выполняются в рамках одной транзакции базы данных.
В этой статье мы сосредоточим внимание на использовании maven-плагина для миграций базы данных.
Добавим flyway maven plugin в
Актуальную версию плагина можно посмотреть в Maven Central.
Список параметров плагина, можно посмотреть в документации. Параметры плагина можно настроить четырьмя различными способами.
2.1. Раздел
Параметры можно указать напрямую в теге в разделе плагина в
Также плагин можно настроить, указав параметры в
Или описать конфигурацию в отдельном
По умолчанию имя файла конфигурации
Если для файла вы используете другое имя (например,
И наконец, параметры могут быть указаны как system properties при вызове maven из командной строки:
Если конфигурация указана несколькими способами, то приоритет будет следующий:
В этом разделе мы рассмотрим необходимые шаги для миграции схемы базы данных на примере in-memory базы данных H2 с помощью maven-плагина. Для конфигурации Flyway мы будем использовать внешний файл.
Для начала, добавим зависимость на H2:
Здесь мы также можем проверить последнюю доступную версию драйвера в Maven Central. Плагин для Flyway добавляем, как было описано ранее.
Создаем в
Приведенная выше конфигурация указывает, что скрипты миграции находятся в каталоге
Схема базы данных для приложения —
Конечно, в параметрах
По соглашениям Flyway имена скриптов миграции должны быть в следующем формате:
Где:
Пример:
Итак, давайте создадим каталог
Далее, в
Должна выполниться наша первая миграция.
Теперь схема базы данных выглядит следующим образом:
employee:
Мы можем повторить предыдущие шаги для выполнения других миграций.
Для второй миграции создаем файл с именем
Выполним миграцию, также как делали для первой миграции.
Теперь схема нашей базы данных изменилась: в
Для проверки, что обе миграции прошли успешно, запустим следующую команду maven:
Иногда может потребоваться отключить Flyway-миграции.
Это может понадобиться во время тестов, когда схема базы данных генерируется на основе сущностей. В этом случае можно отключить Flyway для тестового профиля.
В Spring Boot это сделать очень просто.
Все, что нам нужно сделать, это установить свойство
В более поздних версиях Spring Boot это свойство было изменено на
Если мы хотим отключить только автоматическую миграцию Flyway при запуске, но хотим запускать миграции вручную, то использование вышеописанных свойств нам не подойдет.
Это связано с тем, что Spring Boot не будет автоматически конфигурировать бины Flyway и, следовательно, нам придется настраивать их самостоятельно, что не очень удобно.
В этом случае мы можем оставить Flyway включенным и реализовать пустую FlywayMigrationStrategy:
Фактически это отключит Flyway-миграции при запуске приложения.
Но мы все равно можем запускать миграции вручную:
Для отслеживания когда, кем и какие миграции были применены, в схему базы данных добавляется специальная таблица с метаданными. В этой таблице также хранятся контрольные суммы миграций и информация о том успешна была миграция или нет.
Фреймворк работает следующим образом:
В Flyway есть следующие основные команды по управлению миграциями:
УПРАВЛЯЕМ ВЕРСИЯМИ БАЗЫ ДАННЫХ ЧЕРЕЗ FLYWAY
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
:<plugin>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-maven-plugin</artifactId>
<version>4.0.3</version>
<configuration>
<user>databaseUser</user>
<password>databasePassword</password>
<schemas>
<schema>schemaName</schema>
</schemas>
...
</configuration>
</plugin>
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<code>><</code>Version>__<code><</code>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
Throwable
По большей части бесполезная вещь. В билд-скрипте нужно содержать коннекшн к каждому из environment. Плюс делать миграции с девелоперского компа заведомо неправильно. Миграцию должен делать задеплоенный артефакт при запуске.
Что плохо и неудобно в Flyway, так это то, что все миграции линейны. Это делает их неудобными, если у вас в git-е есть несколько веток. Например если есть версии Vx и Vy, которые друг от друга не зависят, и находятся в разных ветках, то при сливе в master нужно будет вручную переупорядочивать. Кроме того, на бенчах, где уже применился Vy из другой ветки не будет применен Vx, если его версия меньше, а точнее все вылетит с ошибкой. Это требует много ручного геморроя.
foal
Плагин — согласен.
С ветками проблема, да… Возможно вам помогут таймстампы вместо версии и outOfOrder опция. Подробнее тут — stackoverflow.com/questions/9497035/how-to-use-flyway-when-working-with-feature-branches