Введение в Flyway
Flyway представляет собой специализированный инструмент управления миграциями баз данных, реализующий принцип "Database-as-Code". Его фундаментальная задача заключается в обеспечении контролируемого и воспроизводимого процесса эволюции схемы базы данных через систему версионированных изменений.
Ключевые функциональные аспекты:
Декларативное управление схемой - все изменения БД описываются в виде отдельных скриптов
Детерминированность применения - каждая миграция имеет строгую версионную привязку
Атомарность изменений - миграции применяются как единое целое (транзакционно)
Историчность - полный аудит всех выполненных изменений
Сравнение с Liquibase
Принципиальные различия между Flyway и Liquibase проявляются в нескольких аспектах:
Архитектурный подход
Flyway придерживается парадигмы "SQL-первым", где основным носителем изменений являются нативные SQL-скрипты. Liquibase предлагает абстрактный DSL (XML/YAML/JSON) для описания изменений, который затем транслируется в SQL.
Механизм откатов
В Flyway стратегия откатов реализована через создание новых миграционных скриптов с обратными изменениями. Liquibase предоставляет встроенный механизм описания операций отката непосредственно в changeSet.
Сложность и гибкость
Flyway демонстрирует минималистичный подход с низким порогом вхождения. Liquibase предлагает более богатый функционал за счет усложненной модели конфигурации.
Интеграционные возможности
Оба инструмента имеют глубокую интеграцию с экосистемой Java, но Flyway чаще выбирают для Spring Boot-проектов благодаря более простой автоконфигурации.
Базовые концепции
Модель миграций
Flyway оперирует двумя фундаментальными типами миграций:
Версионные миграции (префикс V)
Линейно упорядоченные изменения схемы
Неизменяемые после применения
Пример именования: V2__Add_email_column.sql
Содержимое SQL-скрипта:
Повторяемые миграции (префикс R)
Перезаписываемые скрипты
Применяются при изменении контрольной суммы
Пример: R__Update_report_views.sql
Механизм контроля версий
Система использует служебную таблицу flyway_schema_history, содержащую:
Точную версию каждой примененной миграции
Контрольную сумму скрипта
Временные метки выполнения
Статус операции
Жизненный цикл изменений
Типичный workflow включает:
Инициализацию схемы (baseline)
Валидацию существующих миграций
Применение новых изменений (migrate)
При необходимости - очистку (clean) и повторное развертывание
Поддерживаемые системы управления базами данных
Flyway обеспечивает совместимость с большинством современных реляционных СУБД:
PostgreSQL (полная поддержка, включая расширения)
MySQL/MariaDB (включая специфичные движки хранения)
Oracle (с учетом особенностей PL/SQL)
SQL Server (включая Azure SQL)
Встраиваемые БД (H2, SQLite)
Для NoSQL-систем (MongoDB) требуется использование коммерческой версии Flyway. Важно отметить, что некоторые специфические функции СУБД могут требовать особого подхода при миграциях.
Типовые сценарии использования
Разработка - синхронизация схемы между средами
Тестирование - подготовка изолированных тестовых БД
Развертывание - автоматизация деплоя в production
Анализ - отслеживание истории изменений схемы
#Java #middle #Flyway
Flyway представляет собой специализированный инструмент управления миграциями баз данных, реализующий принцип "Database-as-Code". Его фундаментальная задача заключается в обеспечении контролируемого и воспроизводимого процесса эволюции схемы базы данных через систему версионированных изменений.
Ключевые функциональные аспекты:
Декларативное управление схемой - все изменения БД описываются в виде отдельных скриптов
Детерминированность применения - каждая миграция имеет строгую версионную привязку
Атомарность изменений - миграции применяются как единое целое (транзакционно)
Историчность - полный аудит всех выполненных изменений
Сравнение с Liquibase
Принципиальные различия между Flyway и Liquibase проявляются в нескольких аспектах:
Архитектурный подход
Flyway придерживается парадигмы "SQL-первым", где основным носителем изменений являются нативные SQL-скрипты. Liquibase предлагает абстрактный DSL (XML/YAML/JSON) для описания изменений, который затем транслируется в SQL.
Механизм откатов
В Flyway стратегия откатов реализована через создание новых миграционных скриптов с обратными изменениями. Liquibase предоставляет встроенный механизм описания операций отката непосредственно в changeSet.
Сложность и гибкость
Flyway демонстрирует минималистичный подход с низким порогом вхождения. Liquibase предлагает более богатый функционал за счет усложненной модели конфигурации.
Интеграционные возможности
Оба инструмента имеют глубокую интеграцию с экосистемой Java, но Flyway чаще выбирают для Spring Boot-проектов благодаря более простой автоконфигурации.
Базовые концепции
Модель миграций
Flyway оперирует двумя фундаментальными типами миграций:
Версионные миграции (префикс V)
Линейно упорядоченные изменения схемы
Неизменяемые после применения
Пример именования: V2__Add_email_column.sql
Содержимое SQL-скрипта:
ALTER TABLE users ADD COLUMN email VARCHAR(255);
Повторяемые миграции (префикс R)
Перезаписываемые скрипты
Применяются при изменении контрольной суммы
Пример: R__Update_report_views.sql
Механизм контроля версий
Система использует служебную таблицу flyway_schema_history, содержащую:
Точную версию каждой примененной миграции
Контрольную сумму скрипта
Временные метки выполнения
Статус операции
Жизненный цикл изменений
Типичный workflow включает:
Инициализацию схемы (baseline)
Валидацию существующих миграций
Применение новых изменений (migrate)
При необходимости - очистку (clean) и повторное развертывание
Поддерживаемые системы управления базами данных
Flyway обеспечивает совместимость с большинством современных реляционных СУБД:
PostgreSQL (полная поддержка, включая расширения)
MySQL/MariaDB (включая специфичные движки хранения)
Oracle (с учетом особенностей PL/SQL)
SQL Server (включая Azure SQL)
Встраиваемые БД (H2, SQLite)
Для NoSQL-систем (MongoDB) требуется использование коммерческой версии Flyway. Важно отметить, что некоторые специфические функции СУБД могут требовать особого подхода при миграциях.
Типовые сценарии использования
Разработка - синхронизация схемы между средами
Тестирование - подготовка изолированных тестовых БД
Развертывание - автоматизация деплоя в production
Анализ - отслеживание истории изменений схемы
#Java #middle #Flyway
Настройка и базовые команды Flyway
1. Конфигурация Flyway
1.1. Файл flyway.conf
Основной файл конфигурации Flyway. Располагается в корне проекта или в директории conf.
Пример содержимого:
Ключевые параметры:
flyway.url — JDBC-URL базы данных (формат зависит от СУБД).
flyway.locations — пути к миграциям:
classpath: — поиск в ресурсах проекта (например, src/main/resources/db/migration).
filesystem: — абсолютный путь на диске.
flyway.baselineOnMigrate — инициализация существующей БД (без таблицы flyway_schema_history).
1.2. Параметры командной строки
Настройки можно переопределять через аргументы:
2. Основные CLI-команды
2.1. flyway migrate
Применяет все невыполненные миграции.
Процесс:
Проверяет таблицу flyway_schema_history.
Находит скрипты, которых нет в истории.
Выполняет их в порядке версий (например, V1__... перед V2__...).
Пример:
2.2. flyway info
Показывает текущее состояние БД:
Какие миграции применены.
Какие ожидают выполнения.
Статус (Success, Pending, Failed).
Вывод:
2.3. flyway validate
Проверяет:
Целостность скриптов (не изменены ли уже примененные).
Корректность именования.
Ошибка:
2.4. flyway clean
Удаляет все объекты БД (таблицы, процедуры), включая flyway_schema_history.
Опасность: Необратимая операция. Используется только в dev-среде.
3. Форматы миграций
3.1. SQL-миграции
Стандартный подход. Скрипты с расширением .sql в директории db/migration.
Пример (V1__Create_users.sql):
3.2. Java-миграции
Для сложной логики (например, условные операции).
Шаги:
Создайте класс в проекте:
Укажите путь к Java-классам в flyway.locations:
3.3. Callbacks (SQL-хуки)
Скрипты, выполняемые до/после событий Flyway.
Пример (beforeMigrate.sql):
Поддерживаемые события:
beforeMigrate, afterMigrate.
beforeClean, afterClean.
Директория:
4. Важные замечания
Именование файлов:
Регистрозависимо (V1__test.sql ≠ v1__test.sql).
Разделитель — двойное подчеркивание (__).
Порядок выполнения:
Сначала V1__..., затем V2__....
R__... выполняются после всех версионных.
Безопасность:
Никогда не изменяйте уже примененные скрипты.
Для отката создавайте новые миграции (например, V3__Drop_table.sql).
#Java #middle #Flyway
1. Конфигурация Flyway
1.1. Файл flyway.conf
Основной файл конфигурации Flyway. Располагается в корне проекта или в директории conf.
Пример содержимого:
# Подключение к БД
flyway.url=jdbc:postgresql://localhost:5432/mydb
flyway.user=admin
flyway.password=secret
# Директории с миграциями
flyway.locations=classpath:db/migration,filesystem:/opt/migrations
# Дополнительные настройки
flyway.schemas=public
flyway.baselineOnMigrate=true
Ключевые параметры:
flyway.url — JDBC-URL базы данных (формат зависит от СУБД).
flyway.locations — пути к миграциям:
classpath: — поиск в ресурсах проекта (например, src/main/resources/db/migration).
filesystem: — абсолютный путь на диске.
flyway.baselineOnMigrate — инициализация существующей БД (без таблицы flyway_schema_history).
1.2. Параметры командной строки
Настройки можно переопределять через аргументы:
flyway -url=jdbc:postgresql://localhost:5432/mydb \
-user=admin \
-password=secret \
-locations=classpath:db/migration \
migrate
Важно: Параметры из командной строки имеют приоритет над flyway.conf.
2. Основные CLI-команды
2.1. flyway migrate
Применяет все невыполненные миграции.
Процесс:
Проверяет таблицу flyway_schema_history.
Находит скрипты, которых нет в истории.
Выполняет их в порядке версий (например, V1__... перед V2__...).
Пример:
flyway migrate
2.2. flyway info
Показывает текущее состояние БД:
Какие миграции применены.
Какие ожидают выполнения.
Статус (Success, Pending, Failed).
Вывод:
+-----------+---------+---------------------+------+---------------------+---------+
| Version | Description | Installed on | State | Type | Checksum |
+-----------+---------+---------------------+------+---------------------+---------+
| 1 | Create users | 2024-03-15 10:00 | Done | SQL | 1234abcd |
| 2 | Add email | Pending | | SQL | 5678efgh |
+-----------+---------+---------------------+------+---------------------+---------+
2.3. flyway validate
Проверяет:
Целостность скриптов (не изменены ли уже примененные).
Корректность именования.
Ошибка:
Validation failed: Detected applied migration not resolved locally: 1
Причина: Локальный скрипт V1__... был изменен после применения к БД.
2.4. flyway clean
Удаляет все объекты БД (таблицы, процедуры), включая flyway_schema_history.
Опасность: Необратимая операция. Используется только в dev-среде.
flyway clean
3. Форматы миграций
3.1. SQL-миграции
Стандартный подход. Скрипты с расширением .sql в директории db/migration.
Пример (V1__Create_users.sql):
CREATE TABLE users (
id INT PRIMARY KEY,
username VARCHAR(50) NOT NULL
);
INSERT INTO users (id, username) VALUES (1, 'admin');
3.2. Java-миграции
Для сложной логики (например, условные операции).
Шаги:
Создайте класс в проекте:
public class V2__InsertTestData implements JdbcMigration {
public void migrate(Connection connection) throws Exception {
try (Statement stmt = connection.createStatement()) {
stmt.execute("INSERT INTO users (username) VALUES ('test')");
}
}
}
Укажите путь к Java-классам в flyway.locations:
flyway.locations=classpath:db/migration,classpath:com/example/migrations
3.3. Callbacks (SQL-хуки)
Скрипты, выполняемые до/после событий Flyway.
Пример (beforeMigrate.sql):
-- Выполняется перед началом миграций
CREATE SCHEMA IF NOT EXISTS audit;
Поддерживаемые события:
beforeMigrate, afterMigrate.
beforeClean, afterClean.
Директория:
db/
migration/
V1__...sql
callback/
beforeMigrate.sql
4. Важные замечания
Именование файлов:
Регистрозависимо (V1__test.sql ≠ v1__test.sql).
Разделитель — двойное подчеркивание (__).
Порядок выполнения:
Сначала V1__..., затем V2__....
R__... выполняются после всех версионных.
Безопасность:
Никогда не изменяйте уже примененные скрипты.
Для отката создавайте новые миграции (например, V3__Drop_table.sql).
#Java #middle #Flyway
Типы миграций и версионирование в Flyway
1. Структура SQL-миграций
Flyway классифицирует SQL-миграции по префиксам в именах файлов, определяя их поведение при выполнении.
1.1. Именование файлов
Версионные миграции (Versioned)
Префикс V + версия + описание:
Пример:
Повторяемые миграции (Repeatable)
Префикс R + описание:
Пример:
2. Java-миграции
Позволяют описывать миграции на Java для сложной логики, недоступной в SQL.
2.1. Реализация интерфейсов
JdbcMigration (устаревший):
JavaMigration (рекомендуемый):
2.2. Правила
Классы должны находиться в classpath (обычно src/main/java/db/migration).
Имя класса соответствует имени файла SQL-миграции (например, V2__InsertTestData.java).
3. Правила версионирования
3.1. Семантическое версионирование
Рекомендуемый формат версии:
Пример:
Преимущества:
Понятная история изменений.
Совместимость с Semantic Versioning.
3.2. Откат изменений
Flyway не поддерживает автоматический откат. Альтернативы:
Новая миграция для отмены изменений:
Callbacks (SQL-хуки):
Скрипты beforeMigrate/afterMigrate для резервного копирования.
Важно: Не изменяйте уже примененные миграции — это нарушит целостность flyway_schema_history.
4. Примеры
4.1. SQL-миграции
4.2. Java-миграция
#Java #middle #Flyway
1. Структура SQL-миграций
Flyway классифицирует SQL-миграции по префиксам в именах файлов, определяя их поведение при выполнении.
1.1. Именование файлов
Версионные миграции (Versioned)
Префикс V + версия + описание:
V<Версия>__<Описание>.sql
Пример:
-- V1__Create_users_table.sql
CREATE TABLE users (
id SERIAL PRIMARY KEY,
username VARCHAR(50) NOT NULL
);
Повторяемые миграции (Repeatable)
Префикс R + описание:
R__<Описание>.sql
Пример:
-- R__Update_user_view.sql
CREATE OR REPLACE VIEW user_view AS
SELECT id, username FROM users;
2. Java-миграции
Позволяют описывать миграции на Java для сложной логики, недоступной в SQL.
2.1. Реализация интерфейсов
JdbcMigration (устаревший):
public class V2__InsertTestData implements JdbcMigration {
@Override
public void migrate(Connection connection) throws Exception {
try (Statement stmt = connection.createStatement()) {
stmt.execute("INSERT INTO users (username) VALUES ('admin')");
}
}
}
JavaMigration (рекомендуемый):
public class V3__AddAdminUser implements JavaMigration {
@Override
public void migrate(Context context) throws Exception {
try (Statement stmt = context.getConnection().createStatement()) {
stmt.execute("INSERT INTO users (username) VALUES ('superuser')");
}
}
}
2.2. Правила
Классы должны находиться в classpath (обычно src/main/java/db/migration).
Имя класса соответствует имени файла SQL-миграции (например, V2__InsertTestData.java).
3. Правила версионирования
3.1. Семантическое версионирование
Рекомендуемый формат версии:
V<Мажор>.<Минор>.<Патч>__<Описание>.sql
Пример:
-- V1.2.3__Fix_email_constraint.sql
ALTER TABLE users ALTER COLUMN email SET NOT NULL;
Преимущества:
Понятная история изменений.
Совместимость с Semantic Versioning.
3.2. Откат изменений
Flyway не поддерживает автоматический откат. Альтернативы:
Новая миграция для отмены изменений:
-- V3__Drop_users_table.sql
DROP TABLE users;
Callbacks (SQL-хуки):
Скрипты beforeMigrate/afterMigrate для резервного копирования.
Важно: Не изменяйте уже примененные миграции — это нарушит целостность flyway_schema_history.
4. Примеры
4.1. SQL-миграции
-- V1__Initial_schema.sql
CREATE TABLE users (
id INT PRIMARY KEY,
name VARCHAR(100)
);
-- R__Update_view.sql
CREATE OR REPLACE VIEW active_users AS
SELECT * FROM users WHERE deleted_at IS NULL;
4.2. Java-миграция
public class V4__EncryptPasswords implements JavaMigration {
@Override
public void migrate(Context context) throws Exception {
try (PreparedStatement ps = context.getConnection()
.prepareStatement("UPDATE users SET password = encrypt(password)")) {
ps.executeUpdate();
}
}
}
#Java #middle #Flyway
Интеграция Flyway с инструментами
1. Maven: плагин flyway-maven-plugin
Настройка в pom.xml:
Ключевые параметры:
url — JDBC-строка подключения.
locations — пути к папкам с миграциями (classpath: или filesystem:).
baselineVersion — версия для инициализации существующей БД (если не пустая).
Команды:
2. Gradle: плагин org.flywaydb.flyway
Настройка в build.gradle:
Команды:
3. Интеграция с Spring Boot
Автоконфигурация через application.yml:
Принцип работы:
При старте приложения Spring Boot автоматически:
Проверяет наличие таблицы flyway_schema_history.
Применяет невыполненные миграции из указанных в locations.
Если baseline-on-migrate: true, Flyway инициализирует БД без ошибок, даже если она не пуста.
Важные свойства:
spring.flyway.clean-disabled — запрет на случайную очистку БД (по умолчанию true в prod).
spring.flyway.table — кастомное имя для таблицы истории (по умолчанию flyway_schema_history).
4. Callbacks (SQL-хуки)
SQL-скрипты, выполняемые до/после основных операций Flyway (миграции, очистки и т.д.).
Поддерживаемые события:
beforeMigrate, afterMigrate
beforeClean, afterClean
beforeInfo, afterInfo
Пример использования:
Создайте файл db/migration/beforeMigrate.sql:
Flyway выполнит этот скрипт перед применением миграций.
Правила:
Имена файлов должны соответствовать шаблону: <event>.sql (например, afterMigrate.sql).
Размещаются в папке locations (рядом с миграциями).
5. Мультимодульные проекты (Maven/Gradle)
Если миграции находятся в отдельном модуле:
Укажите путь к ресурсам через filesystem::
6. Пропуск миграций в тестах
В application-test.yml:
7. Кастомные места хранения миграций
S3-хранилище (через Flyway Teams):
Классовый путь + файловая система:
#Java #middle #Flyway
1. Maven: плагин flyway-maven-plugin
Настройка в pom.xml:
<build>
<plugins>
<plugin>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-maven-plugin</artifactId>
<version>9.22.0</version>
<configuration>
<url>jdbc:postgresql://localhost:5432/mydb</url>
<user>postgres</user>
<password>password</password>
<locations>
<location>classpath:db/migration</location>
</locations>
</configuration>
<dependencies>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.6.0</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
Ключевые параметры:
url — JDBC-строка подключения.
locations — пути к папкам с миграциями (classpath: или filesystem:).
baselineVersion — версия для инициализации существующей БД (если не пустая).
Команды:
mvn flyway:migrate # Применить миграции
mvn flyway:info # Показать статус
mvn flyway:clean # Очистить БД (удалить все объекты)
2. Gradle: плагин org.flywaydb.flyway
Настройка в build.gradle:
plugins {
id "org.flywaydb.flyway" version "9.22.0"
}
flyway {
url = 'jdbc:postgresql://localhost:5432/mydb'
user = 'postgres'
password = 'password'
locations = ['classpath:db/migration']
}
dependencies {
flywayRuntime 'org.postgresql:postgresql:42.6.0'
}
Команды:
gradle flywayMigrate # Применить миграции
gradle flywayInfo # Показать статус
3. Интеграция с Spring Boot
Автоконфигурация через application.yml:
spring:
datasource:
url: jdbc:postgresql://localhost:5432/mydb
username: postgres
password: password
flyway:
enabled: true
locations: classpath:db/migration
baseline-on-migrate: true # Игнорировать существующую БД
validate-on-migrate: false # Отключить валидацию (для dev)
Принцип работы:
При старте приложения Spring Boot автоматически:
Проверяет наличие таблицы flyway_schema_history.
Применяет невыполненные миграции из указанных в locations.
Если baseline-on-migrate: true, Flyway инициализирует БД без ошибок, даже если она не пуста.
Важные свойства:
spring.flyway.clean-disabled — запрет на случайную очистку БД (по умолчанию true в prod).
spring.flyway.table — кастомное имя для таблицы истории (по умолчанию flyway_schema_history).
4. Callbacks (SQL-хуки)
SQL-скрипты, выполняемые до/после основных операций Flyway (миграции, очистки и т.д.).
Поддерживаемые события:
beforeMigrate, afterMigrate
beforeClean, afterClean
beforeInfo, afterInfo
Пример использования:
Создайте файл db/migration/beforeMigrate.sql:
-- beforeMigrate.sql
CREATE TABLE IF NOT EXISTS _flyway_audit (
operation VARCHAR(20),
timestamp TIMESTAMP
);
INSERT INTO _flyway_audit VALUES ('migration_started', NOW());
Flyway выполнит этот скрипт перед применением миграций.
Правила:
Имена файлов должны соответствовать шаблону: <event>.sql (например, afterMigrate.sql).
Размещаются в папке locations (рядом с миграциями).
5. Мультимодульные проекты (Maven/Gradle)
Если миграции находятся в отдельном модуле:
Укажите путь к ресурсам через filesystem::
<!-- Maven -->
<location>filesystem:${project.basedir}/../migrations/src/main/resources/db/migration</location>
// Gradle
locations = ['filesystem:../migrations/src/main/resources/db/migration']
6. Пропуск миграций в тестах
В application-test.yml:
spring:
flyway:
enabled: false
7. Кастомные места хранения миграций
S3-хранилище (через Flyway Teams):
spring:
flyway:
locations: s3://my-bucket/db/migration
Классовый путь + файловая система:
locations: classpath:db/migration, filesystem:/opt/migrations
#Java #middle #Flyway
Best Practices и расширенные сценарии работы с Flyway
1. Организация миграций
1.1. Разделение миграций по окружениям
Проблема:
Разные БД для dev/test/prod могут требовать специфичных скриптов (например, тестовые данные только для dev).
Решение:
Структура папок:
Настройка application.yml для dev:
1.2. Работа с существующей БД (baseline)
Проблема:
Flyway ожидает пустую БД или таблицу flyway_schema_history. Если БД уже используется, требуется инициализация.
Решение:
Включить baseline-on-migrate:
Вручную через CLI:
Важно:
После baseline миграции с версией ≤ baselineVersion игнорируются.
2. Тестирование миграций
2.1. Интеграция с Testcontainers + JUnit
Цель:
Проверить, что миграции применяются без ошибок в изолированной БД.
Пример теста (Java + JUnit 5):
Что проверяем:
Применение всех миграций без исключений.
Соответствие схемы ожиданиям (можно добавить проверку через DataSource).
3. Работа в команде
3.1. Именование файлов
Правила:
Уникальность версий:
Используйте дату + порядковый номер: V20240315-1__Add_users_table.sql.
Описательные имена:
Плохо: V1__Changes.sql.
Хорошо: V20240315-2__Alter_users_add_email.sql.
3.2. Запрет изменения примененных скриптов
Проблема:
Изменение уже выполненного скрипта приводит к ошибке:
Решение:
Никогда не изменять содержимое V*-файлов после их применения.
Для исправлений:
Создать новую миграцию с корректировкой:
Если критично, использовать flyway repair (пересчитывает контрольные суммы).
Исключение:
R__-миграции (повторяемые) можно изменять — они переприменяются при изменениях.
4. Расширенные сценарии
4.1. Миграции для нескольких схем БД
Настройка:
4.2. Шаблонизация SQL
Проблема:
Разные SQL-синтаксисы для PostgreSQL/Oracle.
Решение (через Maven/Gradle):
Используйте placeholders в pom.xml:
В SQL:
4.3. Откаты (безопасная альтернатива)
Тактика:
Для деструктивных изменений (DROP, DELETE) создавать "обратные" миграции:
#Java #middle #Flyway
1. Организация миграций
1.1. Разделение миграций по окружениям
Проблема:
Разные БД для dev/test/prod могут требовать специфичных скриптов (например, тестовые данные только для dev).
Решение:
Структура папок:
db/
migration/
dev/
V1__Dev_only_data.sql
prod/
V1__Prod_indexes.sql
common/
V1__Base_schema.sql
Настройка application.yml для dev:
spring:
flyway:
locations: classpath:db/migration/common, classpath:db/migration/dev
1.2. Работа с существующей БД (baseline)
Проблема:
Flyway ожидает пустую БД или таблицу flyway_schema_history. Если БД уже используется, требуется инициализация.
Решение:
Включить baseline-on-migrate:
spring:
flyway:
baseline-on-migrate: true
baseline-version: 1.0 # Версия, с которой начнется контроль
Вручную через CLI:
flyway baseline -baselineVersion="1.0"
Важно:
После baseline миграции с версией ≤ baselineVersion игнорируются.
2. Тестирование миграций
2.1. Интеграция с Testcontainers + JUnit
Цель:
Проверить, что миграции применяются без ошибок в изолированной БД.
Пример теста (Java + JUnit 5):
import org.flywaydb.core.Flyway;
import org.junit.jupiter.api.Test;
import org.testcontainers.containers.PostgreSQLContainer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
@Testcontainers
public class FlywayMigrationTest {
@Container
private static final PostgreSQLContainer<?> postgres =
new PostgreSQLContainer<>("postgres:15");
@Test
void testMigrations() {
Flyway flyway = Flyway.configure()
.dataSource(
postgres.getJdbcUrl(),
postgres.getUsername(),
postgres.getPassword()
)
.load();
flyway.migrate(); // Упадет, если есть ошибки
}
}
Что проверяем:
Применение всех миграций без исключений.
Соответствие схемы ожиданиям (можно добавить проверку через DataSource).
3. Работа в команде
3.1. Именование файлов
Правила:
Уникальность версий:
Используйте дату + порядковый номер: V20240315-1__Add_users_table.sql.
Описательные имена:
Плохо: V1__Changes.sql.
Хорошо: V20240315-2__Alter_users_add_email.sql.
3.2. Запрет изменения примененных скриптов
Проблема:
Изменение уже выполненного скрипта приводит к ошибке:
Validate failed: Migration checksum mismatch for V1__Create_table.sql
Решение:
Никогда не изменять содержимое V*-файлов после их применения.
Для исправлений:
Создать новую миграцию с корректировкой:
-- V20240315-3__Fix_users_table.sql
ALTER TABLE users ALTER COLUMN email SET NOT NULL;
Если критично, использовать flyway repair (пересчитывает контрольные суммы).
Исключение:
R__-миграции (повторяемые) можно изменять — они переприменяются при изменениях.
4. Расширенные сценарии
4.1. Миграции для нескольких схем БД
Настройка:
spring:
flyway:
schemas: public, audit
default-schema: public
В SQL-файлах укажите схему явно:
sql
-- V1__Create_audit_table.sql
CREATE TABLE audit.logs (
id SERIAL PRIMARY KEY,
message TEXT
);
4.2. Шаблонизация SQL
Проблема:
Разные SQL-синтаксисы для PostgreSQL/Oracle.
Решение (через Maven/Gradle):
Используйте placeholders в pom.xml:
<configuration>
<placeholders>
<table.prefix>${env}</table.prefix>
</placeholders>
</configuration>
В SQL:
CREATE TABLE ${table.prefix}_users (...);
4.3. Откаты (безопасная альтернатива)
Тактика:
Для деструктивных изменений (DROP, DELETE) создавать "обратные" миграции:
-- V5__Drop_users.sql
DROP TABLE users;
-- V6__Restore_users.sql (если нужно откатить)
CREATE TABLE users (...); -- Повторяем структуру из V1
INSERT INTO users (...) SELECT ... FROM backup_users;
Использовать резервные копии перед рискованными операциями.
#Java #middle #Flyway