Comments 40
Я с некоторых пор стал предпочитать Testcontainers
неверный подход. Локально, даже для тестирования, надо использовать ту же БД, что и на сервере. Есть же docker сборки или embedded реализации для того же PostgreSQL или OracleDB. В противном случае можно словить коллизии, проявляемые только в конкретной БД конкретной версии и ловить будете эту особенность очень долго
На одном проекте была поддержка одновременно Oracle и Postgres. Прилоежние потом устаналивалось клиентам on-prem.
Соответсвенно тестировалось и на том и на том.
Сам ликвибес был на xml. Иногда вставки СКЛ с добавлением ксловия на то под какой базой запущено.
ох уже эти "швейцарские ножи"… крайне редко "переносимость" делается на раз-два — чаще всего всё равно придётся подкручивать, подтягивать или и вовсе переписывать чтобы заработало на другом окружении (БД, ОС, etc). А если пишете "швейцарский нож", то платите за это например просадкой в производительности
SQL намного интереснее, конечно же. Да и более гибкий, благодаря не только простым инструкциям создания и изменения структуры БД, так еще можно бодро тут же и данными тестовыми наполнять.
- вместо
spring.jpa.hibernate.ddl-auto=none
рекомендую прописыватьspring.jpa.hibernate.ddl-auto=validate
- вместо yaml лучше xml использовать, а ещё лучше — sql файлы. При этом идеально, чтобы одна миграция на один файл с группировкой миграций по дате из создания в подкаталогах — так не попадёте на конфликты при очерёдности исполнения миграций и уйдёте от "портяночных" файлов миграций
покажите пример более-менее сложного SQL запроса внутри миграции и сравните его читабельность с таким же запросом внутри блока CDATA в XML формате
И да, содержимое YAML файла не сильно уступает содержимому SQL файла, а выбирая между "YAML vs SQL" предпочтение отдам последнему, так как валидация и подсветка SQL синтаксиса в той же IDEA однозначно лучше будет + запрос можно выполнить сразу в тестовой БД минуя запуск liquibase
Вы имеете в виду не sql миграции, а ссылки на sql файлы внутри xml, да?
<sqlFile path="file.sql" />
Так?
многовато суеты будет разгребать портянку в одном XML или разбирать последовательность запуска миграций в нескольких сгрупированных XML — легко можно отхватить ситуацию, когда миграция в одном файле ожидает, что уже выполнилась миграция из другого файла, а это не так.
Плюс, в том же Git, гораздо легче сливать небольшие файлики миграций, чем большие — меньше конфликтов получается
смотрел) но
1) я не сторонник описания схемы БД через аннотации Hibernate и автогенераторы — не всё можно прописать или описания через аннотации получается больше чем сама сущность или не всё, что есть в БД надо описывать в сущности. Потому описание миграции руками + validate у Hibernate, что сущность соответствует схеме в минимальном виде
2) как писал уже выше, лучше раскладывать миграции по подкаталогам, а не все в один каталог. Представьте, что у вас по 2-3 миграции в день и вашему проекту уже год и поразгребайтесь в каталоге "db/changelog" после этого. Мы у себя на проекте используем следующую маску: "YYYY/MM/DD_HHmmNNN.xml". Вроде бы как и у вас с timestamp, но уже попроще выглядит содержимое каталога миграций
нет, через includeAll
А как тогда описать rollback для конкретного sql файла?
согласно документации
но я редко (читай — никогда) пишу rollback — чаще preconditions и то, только в том случае, когда они реально нужны.
например, когда добавили что-то "на горячую" в боевой БД, а потом уже написали миграцию, делающую то же самое. Тут пишется preconditions, чтобы миграция пометилась как выполненная, но фактически не выполнялась и то, только если миграция может "упасть" или поломать данные при "повторной" накатке на БД. При этом в остальные окружения эта миграция раскатится в обычном режиме.
Явный пример: когда-то давно в PostgreSQL не было "IF NOT EXISTS" при создание индекса. на проде срочно добавили индекс, а теперь его надо прописать в миграцию. Раньше это решалось только через preconditions. Сейчас обычная миграция c "IF NOT EXISTS"
а "разные скрипты для разных БД" пишутся через "дублирование" changeSet с указанием нужной БД в атрибуте dbms у ChangeSet
Flyway поддерживает миграции для разных БД через суффиксы в имени файла — считай так же, как и Liquibase, только чуть другой формат
Но у Flyway нет preconditions на миграцию — она либо выполняется либо грохается — пометить её как исполненную не исполняя фактически нельзя
При этом мне больше нравится как у Flyway сделана кластерная миграция — делается LOCK на схему, а не флажком в отдельной табличке в БД.
Я лично против того, чтобы включать прогон ликви скриптов при старте приложения. Мне кажется это шаг нужно включать в CI отдельно, до непосредственно запуска приложения. Скрипты бывает выполняются долго, удобно сразу понять, что проблема возникла при миграциях, а не из-за приложения и ещё можно сделать отдельный сервер для тестирования миграций на живых данных.
Использование Liquibase для управления структурой БД в Spring Boot приложении. Часть 1