Contexts
--context-filter
attribute in the CLI. You can specify a
Although there are many use cases for contexts, it is common to use them to specify environments. For example, you may want to indicate that certain changesets should only be run in test
or dev
environments. Contexts are similar to Labels, which you can use to specify other tags, such as assigning a change to a particular feature or version.
In Liquibase Pro 4.23.1+, you can easily set
Uses
By default, a database update runs all undeployed changesets in the changelog. If you add a context to a changeset and use a context filter in the CLI, the update only runs changeset that match the context filter. If you don't specify a context filter in the CLI, every undeployed changeset in your changelog runs, even if they have context attached.
For example, if you want to tag your changesets per environment and run only these changesets, set a context
on each changeset and specify a matching value for --context-filter
in the CLI.
Syntax
Note: If you use Liquibase versions 4.16.0 to 4.23.0, use the syntax contextFilter
instead of context
in your changesets. However, context
is still a supported alias.
--liquibase formatted sql
--changeset bob:1 context:test
insert into news (id, title) values (1, 'Liquibase 0.8 Released')
{
"databaseChangeLog": [
{
"changeSet": {
"id": "2",
"author": "bob",
"context": "test",
"changes": [
{
"insert": {
"tableName": "news",
"columns": [
{
"column": {
"name": "id",
"value": "1"
}
},
{
"column": {
"name": "title",
"value": "Liquibase 0.8 Released"
}
}
]
}
}
]
}
}
]
}
databaseChangeLog:
- changeSet:
id: 2
author: bob
context: test
changes:
- insert:
tableName: news
columns:
- column:
name: id
value: 1
- column:
name: title
value: "Liquibase 0.8 Released"
<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 id="2" author="bob" context="test">
<insert tableName="news">
<column name="id" value="1"/>
<column name="title" value="Liquibase 0.8 Released"/>
</insert>
</changeSet>
</databaseChangeLog>
Context logic
In Liquibase 4.23.0+, you can specify a context using @
in addition to AND
, OR
, !
, and parentheses in the changesets. This requires you to designate a context or label explicitly when Liquibase is run for the changeset to run. The attribute context: @test
causes a changeset to not run if Liquibase runs without any contexts provided.
context="@test"
In Liquibase 3.2.0+, you can specify a context using AND
, OR
, !
, and parentheses in the changesets. Without parentheses, the order of operations is !
, AND
, and then OR
. For example:
context="!test"
context="v1.0 or map"
context="!qa and !main"
Using a ","
to separate contexts works like an OR
operation (a comma is an alias for OR
):
- "
test, qa
" is the same as "test OR qa
" - "
test, qa and main
" is the same as "(test) OR (qa and main)
"
Running contexts
Note: If you use Liquibase 4.23.0 or earlier, use the syntax --contexts
instead of --context-filter
.
You can only specify context filtering logic in a changeset definition, but you can still specify multiple contexts when running Liquibase in the CLI. However, you can only list out all the contexts that apply to the current Liquibase run.
liquibase update --context-filter="test" --changelog-file=example-changelog.xml
If your changelog includes several changesets with complex and simple context filters such as context="qa and main and !dev"
for changeset 1 and context="test"
for changeset 2, you need to pass the following on the command line to deploy them:
liquibase update --context-filter="test,qa,main" --changelog-file=example-changelog.xml
Using contexts for test data
If you manage your test data with Liquibase, it is best practice to have this data in line with all your other changesets, but marked with a "test"
context.
When you want your test data inserted, run a database update and specify the "test"
context in the CLI. When you need to migrate your production database,
don't include the "test"
context, and your test data will not be included.
Note: If you do not specify any contexts in the CLI at runtime, every changeset will
be applied, including those marked with a "test"
context.
If you have multiple test environments or test data sets, simply tag them with different contexts, like "min-test"
and "integration-test"
.
Using contexts to control test data is better than having a separate changelogs tree because later Change Types and changes will be applied to existing test data the same as they are applied to production data. If you had a set of test data that was created and simply added after the database is set up, you would be constantly manually updating your test data scripts to keep them in line with the current database schema.
Multi-DBMS changelogs
If you need to use one changelog for multiple databases, and you only want specific changesets to run on each database, it is possible to use the context
tag to filter them, and then run liquibase update --context-filter="<dbname>"
in your command line. However, this is not recommended. For example:
<changeSet id="1-lawful-evil" author="adrian" context="postgres">
<createTable tableName="my_table">
<column name="id" type="int"/>
</createTable>
</changeSet>
Instead, it is a best practice to use the dbms
tag to differentiate changesets by database type, and then run liquibase update
in your command line. This is a clearer use of contexts and decreases the possibility of errors. You can use context
and dbms
on the same changeset, but only dbms
should refer to your database type. For example:
<changeSet id="1-lawful-good" author="adrian" dbms="postgres">
<createTable tableName="my_postgres_table">
<column name="id" type="int"/>
</createTable>
</changeSet>
<changeSet id="2-lawful-good" author="adrian" dbms="oracle">
<createTable tableName="my_oracle_table">
<column name="id" type="int"/>
</createTable>
</changeSet>
<changeSet id="3-lawful-good" author="adrian" dbms="oracle" context="test">
<createTable tableName="my_oracle_test_table">
<column name="id" type="int"/>
</createTable>
</changeSet>
Default context
You can specify a context attribute in the root DATABASECHANGELOG node to assign that context to all changesets in the changelog by default.
The specified context will have AND
with any context specified in changesets within the changelog file.
include
and includeAll
contexts
You can specify the context attribute in <include>
or <includeAll>
tags. If specified, the given context is added to all changesets in the included file(s).