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 runtime and represent a simple list on each changeset and complex expressions that are supplied at runtime. This means that changesets are tagged with a list of labels (not expressions), and during runtime, you can pass a labelFilter expression to choose the changesets which matches the expression.
Labels work best when the changeset author can simply enumerate or describe what a changeset is used for, such as a particular feature or version. There may be greater complexity at runtime to determine what label expression should be used to perform the deployment, but that control is left to the deployment manager or person executing the changesets. Labels are best if you want to determine any complex filtering logic at runtime, rather than by the changeset author.
In Liquibase Pro 4.23.1+, you can easily set labels in bulk from your command line with the set-labels command instead of specifying them manually in your changelog.
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.
- Assign ticket numbers to particular changesets to track and identify their purpose, such as JIRA ticket numbers
labelFilter runtime syntax
In Liquibase 4.23+, you can specify a label using @
in addition to AND
, OR
, !
, and parentheses in the changesets. The @
is used for labels only at run time and forces any specific labeled changeset to execute.
Example: If a changeset is labeled as label=test
, only this changeset will be forced to execute if at runtime we specify --labels=@test
.
Note: If you have a changeset marked with a labelFilter that starts with @
and you run Liquibase without specifying the --labels
attribute, the changeset will not be executed. If label filters (--labels=
) are specified as @test
at runtime as described in the example above, no changeset will be executed if there are not any labeled titled test
.
Label filters can be specified using @
, AND
, OR
, !
, and ()
(parentheses that are used for grouping). For example:
--labelFilter="@test"
--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 like an OR
operation (a comma is an alias for OR
). 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 control the filter logic in your changesets, use Contexts instead of labels.
- 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
.
Usage
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 --output-file=update.txt update --changelog-file=changelog.xml --labelFilter="1.0 or (1.1 and !shopping_cart)"
If a changeset doesn't have a label, it will always run. If you make a deployment without specifying any labels in the label filter, all changesets will run.
Example: If you run the liquibase update --labelFilter=1.0
command, it will deploy all changesets with the label 1.0
and all changesets without any label. If you run liquibase update
, it will deploy all changesets, whether they have labels or not.

--liquibase formatted sql
--changeset your.name:1 labels:1.0,prod,shopping_cart
CREATE TABLE person (firstname VARCHAR(255) NULL);
--changeset your.name:2 labels:2.0,test
ALTER TABLE person ADD address VARCHAR(255) NULL;
--changeset your.name:3 labels:shopping_cart
ALTER TABLE person ADD favorite_color VARCHAR(255) NULL;
--changeset your.name:4
CREATE TABLE no_label (no_label_col VARCHAR(255) NULL);

<?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="your.name" id="1" labels="1.0,prod,shopping_cart">
<createTable tableName="person">
<column name="firstname" type="VARCHAR(255)"/>
</createTable>
</changeSet>
<changeSet author="your.name" id="2" labels="2.0,test">
<addColumn tableName="person">
<column name="address" type="VARCHAR(255)"/>
</addColumn>
</changeSet>
<changeSet author="your.name" id="3" labels="shopping_cart">
<addColumn tableName="person">
<column name="favorite_color" type="VARCHAR(255)"/>
</addColumn>
</changeSet>
<changeSet author="your.name" id="4">
<createTable tableName="no_label">
<column name="no_label_col" type="VARCHAR(255)"/>
</createTable>
</changeSet>
</databaseChangeLog>

databaseChangeLog:
- changeSet:
id: '1'
author: your.name
labels: '1.0,prod,shopping_cart'
changes:
- createTable:
tableName: person
columns:
- column:
name: firstname
type: varchar(255)
- changeSet:
id: '2'
author: your.name
labels: '2.0,test'
changes:
- addColumn:
tableName: person
columns:
- column:
name: address
type: varchar(255)
- changeSet:
id: '3'
author: your.name
labels: 'shopping_cart'
changes:
- addColumn:
tableName: person
columns:
- column:
name: favorite_color
type: varchar(255)
- changeSet:
id: '4'
author: your.name
changes:
- createTable:
tableName: no_label
columns:
- column:
name: no_label_col
type: varchar(255)

{
"databaseChangeLog": [
{
"changeSet": {
"id": "1",
"author": "your.name",
"labels": "1.0,prod,shopping_cart",
"changes": [
{
"createTable": {
"tableName": "person",
"columns": [
{
"column": {
"name": "firstname",
"type": "varchar(255)"
}
}
]
}
}
]
}
},
{
"changeSet": {
"id": "2",
"author": "your.name",
"labels": "2.0,test",
"changes": [
{
"createTable": {
"tableName": "person",
"columns": [
{
"column": {
"name": "address",
"type": "varchar(255)"
}
}
]
}
}
]
}
},
{
"changeSet": {
"id": "3",
"author": "your.name",
"labels": "shopping_cart",
"changes": [
{
"createTable": {
"tableName": "person",
"columns": [
{
"column": {
"name": "favorite_color",
"type": "varchar(255)"
}
}
]
}
}
]
}
},
{
"changeSet": {
"id": "4",
"author": "your.name",
"changes": [
{
"createTable": {
"tableName": "no_label",
"columns": [
{
"column": {
"name": "no_label_col",
"type": "varchar(255)"
}
}
]
}
}
]
}
}
]
}
include
and includeAll
labels
You can specify the labels
attribute in <include>
or <includeAll>
tags. If specified, the given label is added to all changesets in the included file(s).