Вместо предисловия
Статья будет интересна тем, кто хоть раз задумывался о вопросе наката изменений (патча) на реляционную БД. Статья не будет интересна тем, кто уже освоил и использует Liquibase. Главной целью данной статьи является указание ссылки на репозиторий с примером использования. В качестве примера я выбрал накат sample-схемы HR на БД Oracle (список всех поддерживаемых БД) — любой желающий может скачать себе репозиторий и поиграться в домашних условиях. Желание продемонстрировать пример вызвано обсуждением этого вопроса на ресурсе sql.ru.
Что такое Liquibase
Что такое Liquibase, можно узнать на официальном сайте продукта. Хочется отметить пару хороших статей и на этом ресурсе:
Управление миграциями БД с Liquibase
Использование Liquibase без головной боли. 10 советов из опыта реальной разработки
Почему я использую Liquibase
Мой выбор остановился на этом инструменте, так как:
1) Инструмент отслеживает, какие changeset-ы уже были применены к данному экземпляру БД и накатывает только те, которые еще не накатывались и какие нужно еще донакатить. Если в процессе наката применение какого-либо изменения упало с ошибкой, то, после устранения причины вы перезапускаете накат и Liquibase продолжает выполнение с того changeset-а, на котором остановился.
2) Возможность выставить changeset-у атрибуты runOnChange и runAlways существенно упрощает управление изменениями, в частности, recreatable-объектов.
3) Свойство context позволяет выполнять/не выполнять changeset-ы в зависимости от текущего окружения (например, не запускать юнит-тесты на проде).
Это был не полный список фич.
Репозиторий
Он здесь. В нем приведены "hard" (таблицы, индексы, ограничения целостности) и "soft" (триггеры, процедуры, представления) объекты, changeset-ы с тегами sql и sqlFile, c атрибутами runOnChange и runAlways и без.
Чего нет в репозитории
Ввиду отсутствия необходимости в репозитории нет таких полезных фич/шагов, которые я обычно использую в своих проектах:
- Preconditions — позволяют задавать условие выполнения changeset-a;
- Компилирование объектов схемы в конце наката. В Oracle это dbms_utility.compile_schema(user, false);
- Запуск юнит-тестов.
Комментарии (33)
andreylartsev
02.10.2017 11:05Работает ли инструмент с данными или только со схемой? Если работает с данными то каким образом решается такая проблема что данные в различных окружениях (например в продуктовом и тестовом) должны отличатся?
akk0rd87 Автор
02.10.2017 11:42Да, данные на тесте и проде могут отличаться. А в чем проблема? Сформулируйте.
digrabok
02.10.2017 14:49+1Работает,
просто создаете sql файлы с данными и запускаете их.
Как вы организуете эти файлы под разные энвайронменты — это уже на что фантазии хватит.
Можно просто разные наборы данных иметь, а можно для test подготовить sql который будет править/расширять dev данные.
debose
Пару недель назад внедрял миграции для баз данных. Смотрел на Liquidbase и flywaydb. Выбрали 2й, потому что он понятнее — работает с sql скриптами а не абстракциями. Но даже несмотря на всю простоту, внедрение в команде идёт со скрипом. Пару недель был переходный период когда можно было писать скрипты и для ручного запуска и для автоматического. Команда всё равно выбирала привычный ручной способ. Хотя, вся разница была в том как назвать скрипт и куда положить. Ну и небольшой howto нужно было прочитать.
debose
Я это к тому, что для того чтобы освоиться с liquibase придётся потратить больше времени.
akk0rd87 Автор
А функционал не сравнивали?
SnowBearRu
Вот здесь есть по использованию
stackoverflow.com/questions/37385823/liquibase-vs-flyway-which-one-to-use
akk0rd87 Автор
Благодарю.
debose
С Liquibase я работал пару лет назад. Liquibase мощнее, но и сложнее в освоении.
Из преимуществ Liquibase (о которых я знаю):
Из минусов:
akk0rd87 Автор
Ну то, что ты все changeset-ы в один файл пихал — это ты конечно сам себе злобный Буратино. Ну а уж если, как тут говорят, Liquibase сложнее в освоении, то в сравнении с FlyWay стоит сказать именно так: тяжело в учении, но легко в бою.
debose
Не все так однозначно. Но вводить liquibase в команду даже из 10 человек я не рискнул бы без острой необходимости именно в liquibase-овских фишках.
akk0rd87 Автор
И какую бы альтернативу автоматическому накату изменений ты бы выбрал?
debose
Я же писал. Flyway я выбрал.
akk0rd87 Автор
Что будешь делать, если накат упадет на середине выполнения SQL-файла?
debose
Править скрипт, просить команду быть внимательнее. А если такое будет часто, то писать более гранулярные скрипты. Что тут ещё можно сделать?
akk0rd87 Автор
Это понятно. После того, как ты устранишь причину падения — ты будешь вынужден либо руками удалить из файла уже выполнившиеся команды/операторы, либо запускать руками оставшуюся часть. В случае с Liquibase ты просто нажал бы повторно кнопочку наката.
SyrexS
Не смотрели в сторону dbDeploy? Правда там только порядок выполнения и пропуск выполненных
akk0rd87 Автор
Нет, не смотрел.
debose
Последнее обновление от 2009 года. Я смотрел только на более менее живые проекты.
akk0rd87 Автор
SQL, обвернутый в xml-тег, это уже абстракция?
debose
Абстракция — это описание changeset-a в чистом xml. SQL обёрнутый в тэг — это не абстракция, это извращение. =)
akk0rd87 Автор
Для тех, кто не знает или боится SQL — возможно. Посмотри диаграмму ораколовой команды create table. При желании сделать что-то не предусмотренное xml-нотацией далеко не уедешь. Да и представь себе, я в changeset-ы не только SQL, но и PL/SQL вставляю. Тебе уже стало страшно?
debose
Я ничего не имею против SQLа. Sql-ы в отдельных файлах — на здоровье. А Sql-ы внутри xml тэгов я считаю извращением. Когда ты один пишешь, пиши как хочешь. Но когда так пишет целая команда, то разобраться в том, к чему этот sql был написан (особенно если это pl/sql) проще когда sql отдельно, а xml отдельно.
akk0rd87 Автор
Ну это твое субъективное мнение. А вот тебе мое: если мне нужно сделать десяток alter-ов, зачем я буду плодить столько же файлов, мне проще засунуть их в один xml-файл под разными changeset-ами.
akk0rd87 Автор
Ты хочешь сказать, тебе будет легче разобраться, для чего нужен был конкретный SQL, если он будет в отдельном файле, а не в XML-теге?
debose
Зависит от SQL-a. Если это однострочник типа ALTER TABLE ADD COLUMN — то всё-равно. Если же что-то типа CREATE TABLE, то лучше бы ему быть в отдельном файле.
akk0rd87 Автор
Как прикажешь делать insert-ы, сложные update/merge?
alek_sys
Преимущества абстракций liquibase это:
akk0rd87 Автор
+ Liquibase в отличие от того же Flyway ведет трекинг в бд не по файлам, а отдельным changeset-ам со всеми вытекающими преимуществами.
debose
У flyway даже комментарий в скрипт добавить нельзя после запуска.