Search code examples
liquibase

Mark liquibase-changeSet as run if context doesn't match


I manage my database schema with liquibase and I also want to manage demo-data with liquibase. And now I'm looking for a good strategy for having both together.

My plan is to add a "demo-data"-context to changesets that should insert demo-data. This works. They are ignored (as expected) if I run it with another context.

But what I would like to have is, that they are also marked as run instead of just ignored. In general this is possible with preconditions. But I didn't find a way to make preconditions depending on the context or label.

Do you have an idea how to do that?

Example-Changeset:

<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog
        xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
      http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.1.xsd">
    <changeSet  author="me"  id="1">
        <createTable tableName="users">
            <column  name="id"  type="Integer">
                <constraints  nullable="false"  primaryKey="true"  unique="true"/>
            </column>
            <column  name="firstname"  type="VARCHAR(255)">
                <constraints nullable="false" />
            </column>
            <column  name="lastname"  type="VARCHAR(255)">
                <constraints nullable="false" />
            </column>
        </createTable>
    </changeSet>

    <changeSet  author="me"  id="2" context="demo-data">  
       <preConditions  onFail="MARK_RAN">
            context = demo-data
        </preConditions>

        <insert  tableName="users">  
            <column  name="id"  value="1"/>  
            <column name="firstname" value="Phil"/>
            <column name="lastname" value="Harmony"/>
        </insert>  
    </changeSet>
</databaseChangeLog>

If I run the following two commands I don't want to have demo-data in the database because it is possible, that the database-schema is changed between these two runs. And I also want to avoid to add old demo-data by accident at any point

liquibase update --contexts="any-non-existing-context" // Workaround for "everything except demo-data"
liquibase update --contexts="demo-data"

Solution

  • True, contex is not in the list of supported preconditions, but you can write your own custom precondition that would execute a check on parameter named context with a provided value:

    <preConditions>
        <customPrecondition className="com.example.ContextPrecondition">
            <param name="context" value="demo-data"/>
        </customPrecondition>
    </preConditions>
    

    Take a look at this example from Liquibase docs on how to implement a custom precondition https://contribute.liquibase.com/extensions-integrations/extension-guides/add-a-precondition/