У меня есть рабочая жидкость, интегрированная с Spring-Boot.
application.properties определяет журнал изменений
spring.liquibase.change-log=classpath:db/liquibase-changelog.xml
Для обработки изменений, специфичных для выпуска ниже, в указанный выше файл включены последовательные изменения SQL.
<include file = "changelog/liquibase_release1.sql" relativeToChangelogFile = "true"/>
<include file = "changelog/liquibase_release2.sql" relativeToChangelogFile = "true"/>
<include file = "changelog/liquibase_release3.sql" relativeToChangelogFile = "true"/>
<include file = "changelog/liquibase_release4.sql" relativeToChangelogFile = "true"/>
<include file = "changelog/liquibase_release5.sql" relativeToChangelogFile = "true"/>
Новая функция, представленная в третьей версии, и соответствующее усовершенствование в четвертой версии приложения должны привести к тому, что изменения SQL распространится на liquibase_release3.sql и liquibase_release4.sql.
Теперь требуется перенести эту функцию в первоначальную версию приложения (клиент еще не обновлен до более новой версии). Таким образом, для этого потребуется включить консолидированные изменения SQL, распределенные по liquibase_release3.sql и liquibase_release4.sql, только в liquibase_release1.sql. ПРИМЕЧАНИЕ. Первоначальная версия будет содержать только файл liquibase_release1.sql. Следовательно, мне нужно будет создать уникальный набор изменений в liquibase_release1.sql со всеми консолидированными запросами SQL.
Но моя проблема заключается в том, чтобы справиться со сценарием обновления. Поскольку SQL-запросы теперь будут выполняться только как часть liquibase_release1.sql. Мне нужно пропустить наборы изменений, которые фактически выполнялись бы как часть liquibase_release3.sql и liquibase_release4.sql, чтобы предотвратить повторное выполнение одних и тех же запросов SQL.
Подход 1: Я столкнулся с предварительными условиями, в которых мы можем проверять перед выполнением каждого набора изменений. Для этого нам также потребуется перенести изменения в версии 3 и 4.
Подход 2: Тем временем я наткнулся на оптимальное решение (https://docs.liquibase.com/workflows/liquibase-community/existing-project.html) запустить команду ниже liquibase, чтобы гарантировать, что наборы изменений обрабатываются как уже бегать
liquibase changelog-sync --changelog-file=dbchangelog.xml
Мой план состоит в том, чтобы представить второй XML-файл журнала изменений специально для этой цели и включить liquibase_release3.sql и liquibase_release4.sql. Эти два файла теперь будут включать только те наборы изменений, которые необходимо пропустить (применимо для этой функции) во время обновления. Будет ли это правильный подход? Если описанный выше подход верен, есть ли у нас способ определить синхронизацию журнала изменений в приложении весенней загрузки, например, как мы определяем файл журнала изменений?
Если я все правильно понял, ваш план с двумя разными журналами изменений выглядит перегруженным.
Для таких случаев вы можете использовать Liquibase контексты.
Что-то вроде:
<changeSet id = "foo" author = "bar" context = "contextForVersion4">
.....
</changeSet>
а затем запустите приложение с соответствующим свойством в application.properties
или в качестве параметра командной строки:
spring.liquibase.contexts=contextForVersion4
или если вам нужно несколько контекстов:
spring.liquibase.contexts=contextForVersion1,contextForVersion3
Это приведет к выполнению только наборов изменений с определенными контекстами и пропуску всех остальных.
вы также можете использовать контексты, чтобы пропустить наборы изменений. например <changeSet context = "!yourContext">
Я попробовал решение с использованием контекста. Это пропускает/выполняет упомянутый набор изменений, но не обновляется в таблице журнала изменений. Таким образом, если во время обновления будет обнаружен тот же набор изменений, liquibase все равно попытается выполнить набор изменений, поскольку в файле sql более новой версии не указан контекст. Мне нужен способ, чтобы Liquibase знала, что она должна пропустить этот набор изменений, как будто он считает, что он уже выполнен. Именно по этой причине «синхронизация журнала изменений» является оптимальным решением.
Наконец я нашел прямое и оптимальное решение в подходе 2, не требующее синхронизации журнала изменений.
Мое решение:
Теперь я представил файлы SQL из будущего выпуска, то есть liquibase_release3.sql и liquibase_release4.sql, который содержит только наборы изменений, связанные с функцией, которую необходимо перенести в исходную версию 1. Другие неприменимые наборы изменений удалены.
Теперь Spring.liquibase.change-log=classpath:db/liquibase-changelog.xml содержит три файла вместо исходного liquibase_release1.sql.
<include file = "changelog/liquibase_release1.sql" relativeToChangelogFile = "true"/>
<include file = "changelog/liquibase_release3.sql" relativeToChangelogFile = "true"/>
<include file = "changelog/liquibase_release4.sql" relativeToChangelogFile = "true"/>
При вышеуказанных изменениях наборы изменений для конкретных функций выполняются и обновляются в журнале изменений как уже выполненные. Так что в случае, если приложение обновлено до последней версии. Набор изменений, специфичный для конкретной функции, пропускается, поскольку они уже выполняются как промежуточное (бэкпортное) обновление.
спасибо за быстрый ответ. контексты будут выполнять упомянутый ChangeSET, но мое требование состоит в том, чтобы пропустить несколько изменений, которые следует учитывать во время обновления. Я имею в виду, что Liquibase должна рассмотреть возможность пропуска определенных изменений SET, как будто они уже выполнялись раньше.