How Liquibase Considers A Changeset As Unique

We have a sandbox here in the office that has a database that we run the Liquibase Database Change Log file (a.k.a. “driver file”) against every now and then. We do not develop against this database since one of its purpose is to ensure that the latest version of the driver file runs without problems.

A few days ago, I took a backup of that database and restored it to my local machine. According to the DATABASECHANGELOG table, the driver file was last ran on 17 JUN (see screenshot below). However, when I tried running the latest Liquibase driver file from /develop against my now local db, I got a variety of errors ranging from duplicate key values to tables/columns already existing.

databasechangelog-table

I might have missed the email but last time I checked, the idea was to allow running and re-running of the changesets without having a negative effect and without having the execution error out. I had to exclude a bunch of changeset entries in the driver file to get it to finish without reporting any errors. Below is the list with the reason why it failed:

liquibase-problem-files

An officemate tried to run the latest driver file on his local machine and worked without any problems. We checked the DATABASECHANGELOG table for the existence of the IDs of the changesets and to our surprise, they were already there. The errors being thrown due to the lack of precondition in the changesets are just a manifestation of a different problem altogether (although the lack of precondition on the changeset is a problem on its own). We were able to come to that conclusion because Liquibase will only try and run the changeset if that changeset’s ID is not on the DATABASECHANGELOG table. So why is Liquibase trying to execute a changeset when the ID of the changeset is already in the DATABASECHANGELOG table?

Upon further investigation, we came upon this question on StackOverflow: Liquibase tried to apply all changeset, even if database is present‌
The take away is that Liquibase tracks each changeset as a row in the DATABASECHANGELOG table which is composed of the combination of the “id”, “author” and a “filename” column.

If we go back to the first screenshot above, you’ll notice that the value for the FILENAME column after 17 JUN 2015 has changed. At this point, it means that I’ve restored a backup of that database to my local machine and the path where I’ve been executing Liquibase is different from the path where Liquibase was being executed on the sandbox in the office.

So how did we solve the problem?

1.) We cleaned up the filename column so that it only contains the actual filename of the changeset.*

2.) Made modifications on the way we were executing the driver file moving forward so that the FILENAME column only contains that – the filename without paths. (How To: Execute Liquibase Database Change Log file (a.k.a. “driver file”) from Visual Studio).

fixed-filename-only

.* truncated the DATABASECHANGELOG table, dropped all affected tables and ran the driver file.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s