Labels
Labels are tags that you can add to changesets to control which changeset will be executed in any migration run. Labels control whether a changeset is executed depending on runtime settings. Any string can be used for the label name, and it is case-insensitive.
Labels allow you to choose a subset of changesets to execute at the runtime and represent a simple list on each changeset and complex expressions that are supplied at the runtime. It means that changesets are tagged with a list of labels (not expressions), and during the runtime, you can pass a labelFilter expression to choose the changesets which match the expression.
Uses
You can typically use labels to:
- Manage and track your deployments.
- Apply complex logic to your deployments.
- Mark changesets based on features and then selectively apply those features at the execution time instead of using version control branches.
- Use different languages for marking changesets. For example, you can mark your changesets both with Spanish and English.
labelFilter runtime syntax
Label filters can be specified using AND
, OR
, !
, and ()
(parentheses that are used for grouping). For example:
--labelFilter="!v.0.1"
--labelFilter="v.1.0 and v.1.1"
--labelFilter="v.1.0 or v.1.1"
--labelFilter="!v.1.0 and !v.1.1"
Using ","
to separate labels works the same as an OR
operation. For example:
--labelFilter="v.1.0, v.1.1"
is the same as--labelFilter="v.1.0 OR v.1.1"
--labelFilter="v.0.1, v.1.0 and v.1.1"
is the same as--labelFilter="(v.0.1) OR (v.1.0 and v.1.1)"
You can run the --labelFilter
attribute to determine which changesets in the changelog to evaluate based on its label. Learn more about the labelFilter logic at this blog post.
Note: If you want to tag your changesets and control the filter logic in the CLI, use Labels instead of contexts.
- In your changelog, you can specify only a simple list of labels to apply to the changeset. For example,
labels="v.0.1, v.1.0"
. - At runtime, you can specify a complex expression with the labels that you want to execute. For example,
--labelFilter="!v.0.1"
or--labelFilter="v.1.0 or (v.1.1 and v.1.2)"
.
Note: Prior to version 4.16.0, the CLI argument was --labels
rather than --labelFilter
. In 4.16.0 and beyond, --labels
is a supported alias for --labelFilter
.
How to work with labels
It is best practice to enumerate your changesets or describe what a changeset is used for. An example of labels indicating the version or a specific feature can be "1.0"
or "shopping_cart"
. In this case, labels will allow you to run changes with:
--labelFilter=1.0
to deploy the 1.0 changesets or--labelFilter=shopping_cart
to deploy the changesets related to the shopping cart.--labelFilter="1.0 or (1.1 and shopping_cart)"
to deploy the 1.0 changesets and only the 1.1. features related to the shopping cart.--labelFilter="1.0 or (1.1 and !shopping_cart)"
to deploy the 1.0 changesets and the 1.1. features that are not related to the shopping cart.
You can see an example of running the update
command with complex labelFilter
statements:
liquibase update --changelog-file=changelog.xml --output-file=update.txt --labelFilter="1.0 or (1.1 and !shopping_cart)"
If your changelog includes changesets that have labels and changesets that don't have them, changesets without labels will match any label.
Example: If you run the liquibase update --labelFilter=release3
command, it will deploy all changesets with the label release3
and all changesets without any label.

<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<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="Liquibase User" id="1" labels="1.0" objectQuotingStrategy="QUOTE_ALL_OBJECTS">
<createTable schemaName="proschema" tableName="primary_table">
<column name="name" type="CHAR(20)"/>
</createTable>
</changeSet>
</databaseChangeLog>

--liquibase formatted sql
--changeset Liquibase User:1 labels:1.0
create table primary_table (
id int primary key,
name varchar(50) not null,
address1 varchar(50),
address2 varchar(50),
city varchar(30)
)

databaseChangeLog:
- changeSet:
id: '1'
author: Liquibase User
labels: '1.0'
changes:
- createTable:
tableName: primary_table
columns:
- column:
name: id
type: int
autoIncrement: true
constraints:
primaryKey: true
nullable: false
- column:
name: firstname
type: varchar(50)
- column:
name: lastname
type: varchar(50)
constraints:
nullable: false
- column:
name: state
type: char(2)

{
"databaseChangeLog": [
{
"changeSet": {
"id": "1",
"author": "Liquibase User",
"labels": "1.0",
"changes": [
{
"createTable": {
"tableName": "primary_table",
"columns": [
{
"column": {
"name": "id",
"type": "int",
"autoIncrement": true,
"constraints": {
"primaryKey": true,
"nullable": false
}
}
},
{
"column": {
"name": "firstname",
"type": "varchar(50)"
}
},
{
"column": {
"name": "lastname",
"type": "varchar(50)",
"constraints": {
"nullable": false
}
}
},
{
"column": {
"name": "state",
"type": "char(2)"
}
}
]
}
}
]
}
}
]
}