Ernani
Ernani

Reputation: 339

How to mark ran on all change sets of a changelog using a single pre condition?

I am using liquibase v3.6.3 with postgresql v9.4.

I have a changelog file with over 40 change sets. All of these changes (which consists of adding tables, foreign keys, etc.) have a single condition to run, which is to check if a specific table exists (say, myTable). If this condition is false, that is myTable already exists, I need to mark all changes as executed.

I could do the following on every single change set of the changelog file, which I have already tested and works:

<changeSet>
    <preConditions onFail="MARK_RAN">
        <not>
            <tableExists tableName="myTable" schemaName="public"/>
        </not>
    </preConditions>
    ...my change 1
</changeSet>

<changeSet>
    <preConditions onFail="MARK_RAN">
        <not>
            <tableExists tableName="myTable" schemaName="public"/>
        </not>
    </preConditions>
    ...my change 2
</changeSet>

...

<changeSet>
    <preConditions onFail="MARK_RAN">
        <not>
            <tableExists tableName="myTable" schemaName="public"/>
        </not>
    </preConditions>
    ...my change n
</changeSet>

The issue is I would need to repeat the pre condition for every single change, and repeated code is hardly a good practice.

I could instead add the following at the beggining of the changelog file:

<preConditions onFail="HALT">
    <sqlCheck expectedResult="0"> SELECT COUNT(1) FROM pg_tables WHERE TABLENAME = 'myTable' </sqlCheck>
</preConditions>

This blocks the entire changelog file from being executed, which is one of the results I want. But I also need to mark the changes as executed, which the sqlCheck doesn't do.

Is there a way to add the pre condition with "MARK_RAN" only once and apply it to the all of the change sets in the changelog file? I couldn't find anything like this on the liquibase documentation.

Other types of solutions without pre conditions which also mark the changes as executed are welcome.

Upvotes: 2

Views: 1930

Answers (1)

SteveDonie
SteveDonie

Reputation: 9016

This would be a bit of a hack, but might be a better hack than adding all the preconditions to your changelog.

Start by running the updateSQL command against a clean database. This will generate all the SQL that would be applied to a database to deploy all the changesets. In that SQL file that is generated will be a set of insert statements to the DATABASECHANGELOG table.

Extract all those insert statements into a single file. Call it something like "MarkAllMyTableRelatedAsRan.sql", and then in your first changeset use the <sqlFile> tag to run those inserts, using the precondition.

Upvotes: 3

Related Questions