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 в вашем проекте. Если вы создаете проект с нуля, то особых проблем возникнуть не должно. Если же вы хотите применить его на старых проектах, то у меня есть пара советов:
- Сперва создайте скрипт V1__init.sql, в который поместите полное описание текущей схемы данных. Адекватные СУБД смогут сгенерировать соответствующий скрипит (например, в PostgreSQL это осуществляется утилитой pg_dump с указанием ключа -s)
- У вас не удастся запустить скрипты миграции на уже существующей схеме. Чтобы это осуществить, добавьте в application.properties следующие строки
flyway.baseline-on-migrate=true
flyway.baseline-version=LAST VERSION HERE
Здесь flyway.baseline-version - версия последнего скрипта миграции, который не будет запущен для данной схемы; все скрипты со старшими версиями запущены будут.
И не забудьте убрать эти строки после успешной миграции.
Спасибо за внимание.
Прощайте.