How to apply liquibase change set conditionally
In our recent grails project, we were about to move to production so we decided to manage the database changes with liquibase. So we generated the changelog from development env by executing the command “grails generate-changelog /home/uday/projects/projectName/grails-app/migrations/changelog.xml” which contained all the table creation changesets. We updated the dbCreate=’none’ in all env. When we ran the application in test env, having the database in create-drop mode, it worked, but in other envs, which had database in “update” mode, it started failing. Now we wanted some hook to execute the creation changeset only if the tables did not exist.
We just went through the liquibase site and we got the answer to our problem. The solution was in liquibase PRECONDITIONS. We added the preconditions to the changesets to check whether the table existed or not.
[java]
<changeSet author="uday (generated)" id="1305002274717-1">
<preConditions onFail="MARK_RAN">
<not>
<tableExists tableName="account"/>
</not>
</preConditions>
<createTable tableName="account">
<column autoIncrement="true" name="id" type="BIGINT">
<constraints nullable="false" primaryKey="true"/>
</column>
<column name="version" type="BIGINT">
<constraints nullable="false"/>
</column>
<column name="balance" type="DECIMAL(19,2)">
<constraints nullable="false"/>
</column>
<column name="date_created" type="DATETIME">
<constraints nullable="false"/>
</column>
<column name="last_updated" type="DATETIME">
<constraints nullable="false"/>
</column>
<column name="firstname" type="VARCHAR(255)"/>
</createTable>
</changeSet>
[/java]
In the above example the changeset will execute only if the precondition passes, if the condition fails you can specify what needs to be done. In our case we mark it as run so that liquibase marks it as being executed. You can do other things on fail event like HALT, CONTINUE, WARN,MARK_RAN.
The documentation is quite good, you can find the examples of other changesets like constraints and indexes as well.
Hope it helps