null

Spring Boot и Flyway

Java EE/Spring разработчики при работе с БД зачастую полагаются на возможности чудесной реализации JPA - Hibernate. Мы доверяем Hibernate'у даже создание схемы данных. Но в данной статье я предлагаю отказаться от такого подхода и писать скрипты вручную.

Казалось бы, Hibernate прекрасно справляется с данной задачей, зачем нам делать лишнюю работу? Увы, при чуть более подробном знакомстве всплывают ограничения этого чудесного инструмента. Обнаруживаются проблемы со внешними ключами, с изменениями (добавлением, удалением) различных ограничений, невозможность удалить старую колонку... Данный список опытный разработчик может продолжать еще долго.

Помимо этого в крупных проектах может возникнуть необходимость обращаться к каким-то специфическим свойствам БД - хранимые процедуры, триггеры и т.д. Создать их средствами Hibernate невозможно.

В итоге для решения этих проблем в проекте появляется множество SQL скриптов (от чего разработчики пытались уйти, возлагая всю ответственность на Hibernate). Но мало просто написать эти скрипты - нужно запустить их во множестве различных окружений (тестовые, продукционные, локальные у каждого разработчика). Задача эта рутинная, и хотелось бы ее автоматизировать. И разумеется, для этого есть соответствующие инструменты. Один из них - Flyway.

По своей сути Flyway - это инструмент для запуска набора скриптов миграции для вашей БД. Каждый скрипт имеет имя в формате V<version>__<name>.sql (например, V21__catalogue_entity.sql или V1_1__auto_generate_ids.sql). Версия каждого скрипта имеет значение - Flyway будет запускать только "старшие" версий. Текущая версия вашей схемы в БД определяется по таблице schema_version. Важно отметить, что проверяется не только версия файла, но и хеш его содержимого. Таким образом, если вы запустили скрипты миграции для файла V1__init.sql, после чего поменяли его содержимое (например, заменили табы на пробелы), то следующий запуск завершится ошибкой.

Так как в своей работе я в основном сталкиваюсь с приложениями на Spring Boot'е, для меня весьма приятна легкость в интеграции его вместе с Flyway. Для этого достаточно добавить Flyway в зависимости проекта 

<dependency>
    <groupId>org.flywaydb</groupId>
    <artifactId>flyway-core</artifactId>
</dependency>

и дополнить application.properties следующей строкой

flyway.enabled=true

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

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

  1. Сперва создайте скрипт V1__init.sql, в который поместите полное описание текущей схемы данных. Адекватные СУБД смогут сгенерировать соответствующий скрипит (например, в PostgreSQL это осуществляется утилитой pg_dump с указанием ключа -s)
  2. У вас не удастся запустить скрипты миграции на уже существующей схеме. Чтобы это осуществить, добавьте в application.properties следующие строки
flyway.baseline-on-migrate=true
flyway.baseline-version=LAST VERSION HERE

Здесь flyway.baseline-version - версия последнего скрипта миграции, который не будет запущен для данной схемы; все скрипты со старшими версиями запущены будут.

И не забудьте убрать эти строки после успешной миграции.

Спасибо за внимание.

Прощайте.