Recently we started working with database migrations via Liquibase. Even though we have used ActiveRecord migrations extensively in the past here, because a lot of our work in another part of the team was in liquibase, and the fact that we would run liquibase via a rake task, we decided to go with it.
First thing that hit me is that because Liquibase uses XML as its source code format, it is not as readable as Active::Record migrations, but it does allow a lot of hooks. You can set context on a bunch of migrations and run them together should you want to (something that comes in very handy for seeding a database). Dependencies and pre-conditions are also handled and in case the latter fails, you can set up logical paths of executions. And as is the case with most decent and self respecting migration tools, a roll back is provided.
So recently I wrote a migration to add a few measly rows to the test database and ran it, confirmed execution, removed the data, called the QA over to show her that I had indeed done it. QA comes over, I run the migration, open mysql and show the contents of the database. and what do I get, nothingness :(.
Turns out, that Liquibase, like ActiveRecord writes to the DATABASECHANGELOG table in the database. But unlike the latter, when you rerun something without having run the rollback, it checked the mentioned log table, sees that it was run and exits, without any message to the contrary. So if you were looking at the output of liquibase when you ran it initially and when you ran it a second time, you would see no difference. *insert loud scream*
In conclusion; I like Liquibase, its simple, neat and allows a lot of hooks to do a lot of stuff, but its execution pattern leaves a little bit to be desired. Also, provide rollbacks if you use liquibase, or get in the habit of running
DELETE FROM DATABASECHANGELOG;