Автоматизированный рефакторинг баз данных должен быть частью жизненного цикла разработки наших продуктов наряду с рефакторингом любых других программных компонентов. Исторически так сложилось, что контроль версий исходников покрывал в подавляющем большинстве случаев только так называемый прикладной код (например, Java), исключая SQL, скрипты на котором носили внешний характер и применялись к целевым базам данных, минуя контроль версий.
Тем не менее, в связи с ростом популярности аджайл методологии в последние годы и востребованностью непрерывной интеграции и развертывания, мы больше не можем ограничивать применение CI/CD только к коду приложения, оставив SQL позади.
В аджайл проектах тех требования вырабатываются спринт за спринтом, поэтому очень маловероятно, что вы сможете с самого начала точно угадать со структурой модели базы данных. Модель базы данных развивается по мере формирования продукта. Многие команды и компании разрабатывают собственные процессы контроля версий баз данных, подходящие сугубо для целей их собственных продуктов, но существуют и общие решения, уже приобретшие статус отраслевых стандартов. Им мы и уделим внимание в этой статье.
Ниже будут рассмотрены сходства и различия ныне хорошо известных продуктов Flyway и Liquibase.
Как работают инструменты Flyway и Liquibase
Оба инструмента реализуют концепцию эволюционных баз данных, объясняет Мартин Фаулер.
Вы начинаете с пустой модели базы данных, для которой таблица контроля версий (специфичная для каждого инструмента) также пуста, и еще не были применены никакие скрипты. Затем вы применяете несколько скриптов (Script1 и Script2) и в итоге получаете первую версию базы данных. Скрипты 3 и 4 регистрируются в таблице контроля версий, и мы получаем вторую версию базы данных. Вы всегда знаете имя автора, имя скрипта и его контрольную сумму.
Пример кода
1.Создайте пустой проект maven
mvn archetype:generate -B -DarchetypeGroupId=org.apache.maven.archetypes -DarchetypeArtifactId=maven-archetype-quickstart -DarchetypeVersion=1.1 -DgroupId=robloxro -DartifactId=flywaysample -Dversion=1.0-SNAPSHOT -Dpackage=flywaysample
2. Установите плагин Flyway в pom.xml
(и базу
данных H2, чтобы мы запускали на ней пример).
<project>.....<groupId>robloxro</groupId> <artifactId>flywaysample</artifactId> <version>1.0-SNAPSHOT</version> <packaging>jar</packaging><name>flywaysample</name> <url>http://maven.apache.org</url><build> <plugins> <plugin> <groupId>org.flywaydb</groupId> <artifactId>flyway-maven-plugin</artifactId> <version>5.2.4</version> <dependencies> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <version>1.4.191</version> </dependency> </dependencies> </plugin> </plugins> </build></project>
3. Определите файл конфигурации flyway
flyway.user=saflyway.password=flyway.schemas=INFORMATION_SCHEMAflyway.url=jdbc:h2:~/testflyway.locations=filesystem:.\src\main\resources\db\migration
4. Создайте первый скрипт миграции
create table PERSON ( ID int not null, NAME varchar(100) not null);
5. Выполните первую миграцию
mvn clean flyway:migrate -Dflyway.configFile=myFlywayConfig.properties
Вывод должен быть следующий
Вы также можете проверить базу данных
6. Попробуйте применить тот же скрипт еще раз -
flyway
определит, что версия базы данных осталась
неизменной.
Просто запустите его снова
mvn clean flyway:migrate -Dflyway.configFile=myFlywayConfig.properties
Вывод отобразит
7. Примените вторую миграцию
insert into PERSON (ID, NAME) values (1, 'Axel');insert into PERSON (ID, NAME) values (2, 'Mr. Foo');insert into PERSON (ID, NAME) values (3, 'Ms. Bar');
8. Что произойдет, если я изменю уже примененный скрипт?
Измените в уже существующем примененном файле V2_Addpeople.sql.sql
это
insert into PERSON (ID, NAME) values (3, 'Ms. Bar');
на это
insert into PERSON (ID, NAME) values (3, 'Ms. Barrrr');
Повторный запуск миграции покажет, что Flyway заметил изменение контрольной суммы и не пропустил новую миграцию.
Если вы хотите изменить имя этого человека, вам нужно добавить еще один файл, третий, с командой обновления имени этого человека.
Возможности, предлагаемые Flyway и Liquibase
Как Flyway, так и Liquibase являются инструментами, написанными на Java. Они легко интегрируются с maven, gradle и другими инструментами сборки, что способствует большей кастомизации. Они предлагают Java API и могут быть расширены. Их можно использовать из командной строки или используя их jar параметры.
Оба продукта предлагают
-
контроль версий
-
инкрементное развертывание скриптов (только в случае еще не примененных к целевой базе данных скриптов)
-
предотвращение ситуаций, когда скрипт, примененный к базе данных, был изменен в системе контроля версий вместо инкрементного добавления
-
решения для коррекции развертывания или исправления ситуации, когда скрипт был неправильно изменен
-
параметры контекста - $var - чтобы вы могли настроить модель базы данных, чтобы она подходила для нескольких развертываний на схемах в конвейере CI/CD
-
оба полагаются на таблицы контроля версий с контрольной суммой (Flyway: SCHEMA_VERSION, Liquibase: DATABASECHANGELOG и DATABASECHANGELOGLOCK)
-
baselining - если ваша схема базы данных уже была создана без использования какого-либо из этих инструментов, но вы захотите начать деплоить с их помощью спустя некоторое время после ее создания, вы можете использовать baseline-команды для создания бейслайна схемы поверх которого можно быдет инкрементно добавлять новые скрипты. Бейслайн будет включать DDL, но не данные. Иногда разработчики, запускающие инструмент в первый раз, оказываются сбиты с толку, думая, что бейслайн также мигрирует данные.
В таблице ниже перечислены некоторые из наиболее важных и часто используемых фич этих продуктов. В таблице указаны версии инструментов с открытым исходным кодом, распространяемые по бесплатной лицензии, каждая из которых имеет коммерческие версии с расширенным функционалом.
+------------------------------------+------------------+--------+--+| Feature | Liquibase | Flyway | |+------------------------------------+------------------+--------+--+| Database Source Control/Versioning | yes | yes | || Source Code Control Integrations | yes | yes | || Baseline generation | yes | yes | || Language used for scripts | XML,JSON,YML,SQL | SQL | || Diff Support | yes | no | || Rollback Support | yes | no | || Dynamic Parameter Support | yes | yes | || CLI | yes | yes | || Java API for integration | yes | yes | || Maven,gradle build tools support | yes | yes | || | | | |+------------------------------------+------------------+--------+--+
Общие сценарии использования для FlyWay и Liquibase
Оба инструмента предлагают все мощные функции, необходимые для полной автоматизации рефакторинга и эволюционной модели базы данных. Они легко интегрируется в экосистему Spring, хорошо работают с maven, gradle, java.
Вам следует использовать эти инструменты для обеспечения
-
контроля версий для всех артефактов баз данных
-
аудита изменений модели базы данных
-
чтобы каждый в команде имел собственное развертывание базы данных
-
предотвращать развертывания, когда база данных не синхронизирована с приложением
-
создавать новые среды
-
заставлять разработчиков непрерывно интегрировать свой код базы данных
Когда следует использовать Flyway, а когда Liquibase
Flyway использует SQL, что упрощает жизнь разработчикам. Я
обнаружил, что разработчики баз данных не рады работать с
xml-тегами Liquibase, предпочитая <sql>
. Тем не
менее, сила Liquibase заключается в том, что, учитывая, что он
работает с XML или JSON, вы можете использовать его в средах, в
которых база данных использует разные языки на разных машинах (из
личного опыта: H2 на dev, Oracle на test).
В Liquibase есть автоматически генерируемые скрипты отката, если
вы используете xml-теги, которые позволяют автоматически
генерировать откат. Сюда входят простые теги, такие как создать
таблицу, добавить столбец и т. д., для которых движок может легко
определить откат. Для более сложных скриптов со сложной
бизнес-логикой, с использованием <sql>
тегов
Liquibase внутри, вам нужно писать откаты самостоятельно.
Также я использовал DIFF в Liquibase, которого нет в Flyway, он позволяет сравнивать две схемы базы данных и определять их различия.
Также вы можете сделать одну вещь с помощью обоих инструментов встроить создание обязательных скриптов отката в процесс CI/CD. В одном из моих проектов при каждом pull-реквесте инкрементальных скриптов базы данных сервер сборки выполнял сборку pull-реквеста, в рамках которой мы выполняли и скрипты отката для выделенной схемы CI. Если для одного скрипта не предусмотрен откат, или если выполнение отката завершилось неудачно, сборка завершалась ошибкой.
Ограничения
У каждого инструмента есть свои ограничения. Некоторые из них не актуальны в коммерческих версиях (например, атомарный откат в Flyway доступен только в коммерческой версии).
Тем не менее, вкратце, это единственные ограничения, с которыми я столкнулся в своем опыте работы с обоими инструментам:
-
Вам нужно всегда использовать инструмент при развертывании. Если вы работаете в компании, в которой некоторые команды не хотят работать с этим инструментом, а вместо этого применяют скрипты вручную, ничего не получится.
-
Baselining с данными невозможен. Это связано с тем, что средства этих инструментов не связаны с миграцией данных, поэтому разумно не определять базовый уровень данных, а использовать соответствующие специальные задачи DBA для выравнивания данных.
На правах рекламы
А прямо сейчас в OTUS действует новогодняя скидка на все курсы. Рекомендуем обратить внимание: