spring-bootliquibase

Liquibase skip particular changeSET during upgrade


I have a working liquibase integrated with spring-boot.

application.properties defines the changelog

spring.liquibase.change-log=classpath:db/liquibase-changelog.xml

To handle release specific changes below sequential SQL changes are included in the above file

<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"/>

A new feature introduced during third version and related enhancement during the forth version of the application has to lead to SQL changes spread across liquibase_release3.sql and liquibase_release4.sql.

Now the requirement is to backport the feature to initial release of the application(Client not yet upgraded to newer version). So this will require consolidated SQL changes spread across liquibase_release3.sql and liquibase_release4.sql to be included in liquibase_release1.sql alone. NOTE: The initial release would only have liquibase_release1.sql file. Hence I will need to create an unique changeSET in liquibase_release1.sql with all the consolidated SQL queries.

But my problem is to handle the upgrade scenario. Since the SQL queries will now be executed as a part of liquibase_release1.sql alone. I need to skip changeSETs that would have actually executed as a part liquibase_release3.sql and liquibase_release4.sql to prevent re-execution of same SQL queries.

Approach 1: I came across preConditions where we can have check before excecution of each changeSET itself. For this we would require preConditions changes to be pushed to release 3 and 4 also.

Approach 2: Meanwhile I came across an optimal solution(https://docs.liquibase.com/workflows/liquibase-community/existing-project.html) to run below liquibase command to ensure that the changesets are treated as already run

liquibase changelog-sync --changelog-file=dbchangelog.xml

My plan is to introduce a second changelog xml file just for this purpose and include liquibase_release3.sql and liquibase_release4.sql. These two files will now include only those changeSETs which needs to be skipped(applicable for the feature) during upgrade. Will this be right approach? If the approach above is correct, do we have a way to define changelog-sync in spring boot application, like how we define the change-log file?


Solution

  • I finally found the straight forward and optimal solution in Approach 2 without requiring to execute changelog-sync.

    My Solution:

    I now introduced SQL files from future release i.e., liquibase_release3.sql and liquibase_release4.sql which has only changeSETs related to the feature needed to be backport to initial release 1. Other non applicable changeSETs are removed.

    Now spring.liquibase.change-log=classpath:db/liquibase-changelog.xml has three files instead of the original 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"/>
    

    With the above changes the feature specific changeSETs are executed and updated in the changelog as already executed. So in case the application is upgraded to latest version. The feature specific changeSET are skipped since they are already executed as a part intermediate(backport) upgrade.