6

I am looking for best practices on when to use preConditions in Liquibase changeSet. I understand the fact that it helps in checking the existing state of the db and then applies the change. If I am going to use Liquibase from the beginning and all the changes will be done via Liquibase should not changeSet be enough to check/validate the existing state? Writing preConditions seems to me more redundant in such case. I haven't been able to find any good document on this.

In my use case I will be using Liquibase for db schema change + adding metadata in couple of tables. I see some examples for db schema change queries like adding table, column etc where preConditions have been used. But not seeing much around normal insert, update, delete queries. Is it good a practice to write preConditions for such data manipulation queries as well? Is there any good documentation on this?

htshame
  • 6,599
  • 5
  • 36
  • 56
Shanmugam Sundaram
  • 143
  • 1
  • 2
  • 8

2 Answers2

11

Yes - you should write preConditions. On each and every changeSet. Always. Your changeSets should be atomic, so writing preConditions for them should not be hard at all. It just takes a little self-control.

No - changeSet id is not enough to check/validate the existing state. It could be enough in the ideal world, where everything's running extremely smooth, there're no errors and no one is messing with the database with their dirty hands. Or someone can insert some other changeSet in the middle of your databaseChangeLog and the ideal flow, based only on the sequence and identity of changeSets will be broken.

But our world is not ideal, so No, changeSet's ID is not enough. You need preConditions.

Also, check out this question if you want to know more about how the identity of the changeSet is determined.


To answer the second part of your question about checking the data before executing insert, update and delete queries:

You can always use <sqlCheck> tag.

<changeSet id="foo" author="bar">
    <preConditions onFail="MARK_RAN">
        <sqlCheck expectedResult="0">
            SELECT COUNT(*) FROM user WHERE full_name='John Doe';
        </sqlCheck>
    </preConditions>
    <sql>
       <!-- your custom SQL query here which modifies data somehow -->
    </sql>
</changeSet>
Community
  • 1
  • 1
htshame
  • 6,599
  • 5
  • 36
  • 56
4

Since "Best Practice" type questions rarely have a single correct answer, I'll add my own.

My company runs a single monolithic app and has been using liquibase for change management for 5+ years. We're a team of 4 developers and have deployed our app on 100+ servers. We never use preconditions, and I don't recall ever having a liquibase problem where a precondition would have helped. On the other hand, we're pretty diligent about not making db changes except through liquibase EXACTLY BECAUSE we rely on this assumption.

Just make sure everyone is on the same page, and you should be fine.

Note: I found this question as I'm investigating preconditions because we're writing another app that's going to share part of the monolith's schema. Because the changelog would then be logically distributed amongst multiple projects being evolved independently, our assumptions may no longer hold. Keep this in mind if you're planning to share the database across multiple projects.

Marty Neal
  • 8,741
  • 3
  • 33
  • 38