How to set up Liquibase with an Existing Project and Multiple Environments
The Getting Started Guide works when you want to use Liquibase on a new environment with an empty changelog file that matches your empty database. However, when you have multiple environments and want to set up Liquibase with all of them to match your current database schema, the process differs.
For example, you have an HR database and two different environments called: HR_Dev
and HR_Test
, and you want them all to match your HR database.
You will learn how to introduce Liquibase to your HR_Dev
and HR_Test
database environments without affecting your current database schema. You will create a changelog file that matches the current state of your HR database and then apply this changelog file to the HR_Dev
and HR_Test
databases so it will match all the environments.
Step 1: Create a changelog
First, you will create a changelog file that contains all the SQL changes from your existing project. In this example we will use the source HR database. You can create a changelog file to match your HR database manually or it can be done automatically by using the generate-changelog
command.
Note: For any database larger than a few tables, use the generate-changelog command.
To run the generate-changelog
command, specify the driver, class path, URL, and user authentication information in the Liquibase properties file. For more information, see Create and Configure a liquibase.properties File. You can also specify these properties in your command line.
Then run the generate-changelog
command:
liquibase generate-changelog --changelog-file=dbchangelog.xml
Note: Enter the name of the changelog that you want to use in place of dbchangelog.xml
.
The generate-changelog
command generates a changelog file that contains all your objects (represented as changesets) and places the file in the same directory where the command was run.
Note: If there is a project that requires working on multiple schemas in one workflow, you can have the changelog containing multiple schemas by adding the following flags --schemas=<schema1>,<schem2>,<schema3>
and --include-schema=true
to the generate-changelog
command.
The changelog file name extension determines the format of the changelog, so if you specify the file name as changelog.xml
, you will get an XML formatted changelog. Likewise, if you specify the file name as .yaml
, .json
, or .sql
, you will get changelogs formatted in YAML, JSON, or SQL, respectively.
Note: If you generate an SQL formatted changelog, specify the type name of the targeted database as a part of the file name:
changelog.<db_type>.sql
Note: Liquibase does not always detect complex structures like stored procedures or details like an index that is not clustered. Once you have generated a changelog, inspect the output. Review the generated changesets and ensure that the data types look as expected.
XML changelog example
This is the result of running the generate-changelog
command on our sample database. Your changelog will contain changes from your database.
<?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"
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xmlns:pro="http://www.liquibase.org/xml/ns/pro"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsd
http://www.liquibase.org/xml/ns/dbchangelog-ext
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd
http://www.liquibase.org/xml/ns/pro
http://www.liquibase.org/xml/ns/pro/liquibase-pro-latest.xsd">
<changeSet author="diff-generated" id="1185214997195-2">
<createTable name="DEPT">
<column name="DEPTNO" type="NUMBER(2,0)"/>
<column name="DNAME" type="VARCHAR2(14,0)"/>
<column name="LOC" type="VARCHAR2(13,0)"/>
</createTable>
</changeSet>
<changeSet author="diff-generated" id="1185214997195-6">
<createIndex indexName="PK_DEPT" tableName="DEPT">
<column name="DEPTNO"/>
</createIndex>
</changeSet>
<changeSet author="diff-generated" id="1185214997195-7">
<createIndex indexName="PK_EMP" tableName="EMP">
<column name="EMPNO"/>
</createIndex>
</changeSet>
<changeSet author="diff-generated" id="1185214997195-8">
<addPrimaryKey columnNames="DEPTNO" tableName="DEPT"/>
</changeSet>
</databaseChangeLog>
Step 2: Populate the DATABASECHANGELOG tracking table
Once you have your changelog file, populate the DATABASECHANGELOG tracking table with the changesets from this changelog.
Liquibase keeps track of your already deployed changes with the help of its DATABASECHANGELOG tracking table.
To create this table for the first time, use the changelog-sync
command. The changelog-sync
command will populate the DATABASECHANGELOG table with the changesets metadata as if you have been using Liquibase all along.
Another approach you can choose is to add the contexts.
Running the changelog-sync-sql
and changelog-sync
commands:
- Run the
changelog-sync-sql
command to inspect the SQL and ensure that everything looks good before executing thechangelog-sync
command:
liquibase changelog-sync-sql --changelog-file=dbchangelog.xml
Note: Enter the name of the changelog that you want to use in place of dbchangelog.xml
.
changelog-sync
command to ensure that the changesets are treated as already run since they exist in our HR database. The command will mark the changesets in the changelog file as already deployed. This will prevent Liquibase from attempting to redeploy those changesets next time when you run the update command.liquibase changelog-sync --changelog-file=dbchangelog.xml
Note: Enter the name of the changelog that you want to use in place of dbchangelog.xml
.
Adding the contexts
Alternatively, you can add contexts to the changesets such as <changeSet ... context="legacy">
:
<changeSet author="diff-generated" id="1185214997195-8" context="legacy">
<addPrimaryKey columnNames="DEPTNO" tableName="DEPT"/>
</changeSet>
The contexts can be added to the changeset to control which changeset will be executed in any run. Only the changesets marked with the specific contexts in your changelog that are used with the --context-filter
flag at runtime will be deployed.
- When you run the changelog on the
HR_Dev
andHR_Test
database environments, enter the following:
liquibase update --context-filter=legacy
liquibase update --context-filter=non-legacy
After creating a changelog and populating the HR DATABASECHANGELOG table with the changelog-sync
command or with the contexts, you can now deploy this generated changelog to the HR_Dev
and HR_Test
database environments that need to match you HR database.