Search code examples
liquibasechecksumvoltdb

Liquibase : How to use <preconditions> with changeset having runAlways true?


In my project, we used voltdb as database and we used liquibase for managing version and etc. We wrote changesets in one file and for voltdb and we used RunAlways.xml file which contains below steps

  • drop a procedure
  • create a jar file for all procedures
  • create a procedure in which changes were done
  • create partition if needed

RunAlways.xml file ran after update of existing DB or for new DB also.

Let's say my change set for any procedure is

<changeSet dbms="voltdb" author="foo" id="foo-1" runAlways="true">
        <sql>DROP PROCEDURE BAR</sql>
        <rollback/>
</changeSet> 

Now I changed the <sql> statement and and changed statement is look like this

<sql>DROP PROCEDURE BAR IF EXISTS</sql>

After chnaging this I got Unable to update database. liquibase.exception.ValidationFailedException: Validation Failed: error.

As per one Liquibase blog if we reformat the <sql> tage then it will affect the checksum.

So that I add <validCheckSum>ANY<validCheckSum> tag before <sql> tag. Now when ever RunAlways.xml will run it will not check for checkSum and run always my chnageSet without any error.

Now my question is, Instead of <validCheckSum> tag rather I want to use <preconditions> tag then how should I implement this? I found in on Liquibase blog that we can handle using <preconditions> tag also.

Also there are other solutions as well like clearchecksums command and etc.

Prompt assistance will be highly appreciated.


Solution

  • There is a good argument that runAlways should ignore checksum errors, but currently it doesn't.

    Adding the validCheckSum probably makes the most sense so I'd suggest just sticking with that. It is the most explicit way of saying "This changeset may change from time to time and that is fine".

    Adding runOnChange="true" in addition to the runAlways="true" would work too, but is a bit less obvious to people reading the changelog file what you are intending.

    Clear-checksums is more for one-time/one-off "everything is changed" cases so not something to use on a regular basis like you seem to be looking for.

    Preconditions are a way to add logic to dynamically determine if a changeset should run or not. For example, if your database didn't support the drop ... if exists syntax, you would have to use one to see if the procedure exists before trying to drop it on a runAlways=true changeset.

    You may be able to replace all the runAlways=true attributes with a combination of preconditions and/or runOnChange=true settings which dynamically detect new versions of changesets and the current state of the database to determine what should run. Whether that is more complex or less complex than runAlways=true is a judgement call for you to make.