What is property substitution?
Last updated: September 2, 2025
Liquibase allows a dynamic substitution of properties in your changelog. The tokens to replace in your changelog are described using the ${property-name}
syntax.
Uses
By substituting values for replacement tokens in the format of ${property-name}
, you can use the same changesets to reflect small environmental changes.
For example, your tablespace name in Oracle may differ from environment to environment, but you want to only write one create table changeset that can be used in all of your environments.
Using property substitution in your changelog
You can set property values in Liquibase in several ways. Liquibase assigns these values in the following order:
As an attribute passed to your Liquibase runner. See the Ant, Maven, or Servlet Listener documentation for more information on how to pass them.
As a JVM system property. See JAVA_OPTS Environment Variable for more information.
As an environment variable.
As a CLI attribute, if executed from the command line. Use the syntax
liquibase <command.name> -D<property.name>=<property.value>
. On Windows, surround the property name in quotation marks if it contains a dot. For example:-D"property.name"=value
.In the parameters block (property element of the changelog file itself).
Once a property has been set, it cannot be changed. Also, only the first definition is used, others are skipped.
Note: If the content of ${property-name}
does not match a property, it is left as-is and it is not removed. The supported format includes alphanumeric characters, +
, -
, .
, and _
.
Defining properties with contexts
You can define multiple values for the same property by associating each with a specific context. Looking at the following example code, when Liquibase runs with --context=DEV
, the ${tblsp.name}
token will be replaced with tblsp_cms_dev
. This lets you safely use a single changelog across all environments.
Be sure to place <property>
tags at the beginning of the changelog, before any <changeSet>
definitions.
<property name="tblsp.name" value="tblsp_cms_dev" context="DEV"/>
<property name="tblsp.name" value="tblsp_cms_test" context="TEST"/>
<property name="tblsp.name" value="tblsp_cms_qa" context="QA"/>
<property name="tblsp.name" value="tblsp_cms" context="UAT,PROD"/>
Example Changelog with context-based properties
The first 3 lines of this example changelog provide an additional example of context-based properties being used.
<property name="TS_NAME" value="DEV_TS" context="DEV"/>
<property name="TS_NAME" value="TEST_TS" context="TEST"/>
<property name="TS_NAME" value="PROD_TS" context="PROD"/>
Example Changelog with context-based properties
The first 3 lines of this example changelog provide an additional example of context-based properties being used.
<changeSet id="27" author="liquibase">
<createTable tableName="actor" tablespace="${TS_NAME}">
<column name="id" type="INTEGER"/>
<column name="firstname" type="VARCHAR(255)"/>
<column name="lastname" type="VARCHAR(255)"/>
<column name="twitter" type="VARCHAR(15)"/>
</createTable>
</changeSet>
--liquibase formatted sql
--changeset example:1
CREATE TABLE ${schema.name}.person
( id int primary key,
first_name varchar(50) NOT NULL,
last_name varchar(50) NOT NULL
)