8

I have already implemented Liquibase with Maven. We are currently using a single database (db2) but now we need to add a new database to the application which will have different objects.

I've seen that i can define a new profile in maven but i couldn't find out how to differentiate which objects is being created on which database.

Is there a solution to this? Can I support 2 different databases with different objects using liquibase?

2
  • 1
    How you configure liquibase? cdi, spring, etc. Or you just execute mvn to proccess the migrations? Commented Aug 18, 2014 at 14:27
  • @AVolpe: we are using maven in order to process the db changes. Commented Aug 20, 2014 at 7:58

5 Answers 5

5

As you can see in the documentation, you can use two different executions, like this:

<plugin>
  <groupId>org.liquibase</groupId>
  <artifactId>liquibase-maven-plugin</artifactId>
  <version>3.0.5</version>
  <executions>
    <execution>
      <phase>process-resources</phase>
      <configuration>
        <changeLogFile>PATH_TO_CHANGELOG_1</changeLogFile>
        ... connection properties  ...
      </configuration>
      <goals>
        <goal>update</goal>
      </goals>
    </execution>
   <execution>
      <phase>process-resources</phase>
      <configuration>
        <changeLogFile>PATH_TO_CHANGELOG_2</changeLogFile>
        ... connection properties  ...
      </configuration>
      <goals>
        <goal>update</goal>
      </goals>
    </execution>
  </executions>
</plugin>

The only problem with this approach is that you need two different changelog.xml files, one per database.

Also, you can have preconditions in your changelog file to choose between what changeset will be processed by each database.

For example:

<changeSet id="1" author="bob">
    <preConditions onFail="MARK_RAN">
         <dbms type="oracle" />
    </preConditions>
    <comment>Comments should go after preCondition. If they are before then liquibase usually gives error.</comment>
    <dropTable tableName="oldtable"/>
</changeSet>

The onFail="MARK_RAN" makes Liquibase skip the changeset but marks it as run, so the next time it will not try again. See the customPrecondition tag in the documentation for more complex preconditions.

Sign up to request clarification or add additional context in comments.

3 Comments

How to provide PATH_TO_CHANGELOG_1 as path inside a maven artifact which is already added as a dependency?
Make sure that version is provided along with artifactId. For some reason, it doesn't inherit from parent pom.
Since with this approach the command mvn liquibase:updatedoesn't work , how can I make rollbacks?
4

You may want to have 2 separate changelogs to manage the two databases, even if they are both used by the same application.

Comments

1

As Arturo says you can have 2 or more execution-nodes, but you must give every execution-node a seperate id.

                <plugin>
                    <groupId>org.liquibase</groupId>
                    <artifactId>liquibase-maven-plugin</artifactId>
                    <version>3.0.5</version>
                    <executions>
                        <execution>
                            <id>db1-update</id>
                            <phase>process-resources</phase>
                            <configuration>
                                <changeLogFile>src/main/resources/org/liquibase/db1.xml</changeLogFile>
                                <driver>org.postgresql.Driver</driver>
                                <url>jdbc:postgresql://localhost/db1</url>
                                <username>..</username>
                                <password>..</password>
                            </configuration>
                            <goals>
                                <goal>update</goal>
                            </goals>
                        </execution>
                        <execution>
                            <id>db2-update</id>
                            <phase>process-resources</phase>
                            <configuration>
                                <changeLogFile>src/main/resources/org/liquibase/db2.xml</changeLogFile>
                                <driver>org.postgresql.Driver</driver>
                                <url>jdbc:postgresql://localhost/db2</url>
                                <username>...</username>
                                <password>...</password>
                            </configuration>
                            <goals>
                                <goal>update</goal>
                            </goals>
                        </execution>
                        <execution>
                            <id>db3-update</id>
                            <phase>process-resources</phase>
                            <configuration>
                                <changeLogFile>src/main/resources/org/liquibase/db3.xml</changeLogFile>
                                <driver>org.postgresql.Driver</driver>
                                <url>jdbc:postgresql://localhost/db3</url>
                                <username>...</username>
                                <password>...</password>
                            </configuration>
                            <goals>
                                <goal>update</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>

Comments

1

You can use Preconditions inside changeset or changelog and give conditions according to the database,

<preConditions  onFail="WARN">
    <dbms  type="oracle"  />
    <runningAs  username="SYSTEM"/>
</preConditions>

Like this, you can use precondition tag inside changeset and give conditions according to each database.

Use this link for additions documentation.

Comments

1

Old question but I still answer cause I have the same requirement today, and I am opting for another solution.

I would recommend, if you can, as proposed already in the answers to use seperate changelogs.

But if you want to keep the changelogs unified, as I need for my specific case, I would use labels instead of preconditions to filter changesets to be executed.

<changeSet id="0001:1" author="oz" labels="clickhouse">
    <sql>...SOMESQL...</sql>
</changeSet>

<changeSet id="0001:2" author="oz" labels="mongodb">
    <ext:createCollection collectionName="myCollection">
         ...SOMEJSON....
    </ext:createCollection>
</changeSet>

This will prevent poluting the databasechangelog of the two databases with the executions of the changesets of the other database. This will cause problems(for the current release at least 4.6.1) for any liquibase operation using tags, such as rollbackToTag or updateToTag.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.