Skip to main content

How to manage database migrations with Liquibase changelogs

Use Liquibase changelogs to define schema changes declaratively, apply them with update, roll back safely, and scope changes per environment with contexts and labels.

Difficulty
Intermediate
Duration
40 minutes
Steps
6

What and why

Liquibase tracks schema changes as discrete changesets in a changelog. Unlike pure SQL tools, it supports declarative formats, automatic rollbacks for many operations, and conditional execution by context. It suits teams that need cross-database portability and safe rollbacks.

Prerequisites

  • A database with an account that can alter schema.
  • The Liquibase CLI (or the Docker image) plus the JDBC driver for your database.
  • A project directory for changelog files.

Steps

1. Install Liquibase

docker run --rm liquibase/liquibase --version

2. Create the master changelog

Create changelog.yaml:

databaseChangeLog:
  - include:
      file: changes/001-create-users.yaml

Configure connection details in liquibase.properties:

url: jdbc:postgresql://localhost:5432/app
username: app
password: ${DB_PASSWORD}
changeLogFile: changelog.yaml

3. Add a changeset

Create changes/001-create-users.yaml:

databaseChangeLog:
  - changeSet:
      id: 1
      author: vibgrate
      changes:
        - createTable:
            tableName: users
            columns:
              - column: { name: id, type: BIGINT, autoIncrement: true, constraints: { primaryKey: true } }
              - column: { name: email, type: VARCHAR(255), constraints: { nullable: false, unique: true } }

Each changeset is identified by id + author + file path and runs exactly once.

4. Apply with update

liquibase update

Liquibase records applied changesets in DATABASECHANGELOG and locks with DATABASECHANGELOGLOCK to prevent concurrent runs.

5. Roll back a change

Undo the last applied changeset:

liquibase rollbackCount 1

For changes Liquibase cannot auto-reverse (like raw SQL), add a rollback block to the changeset.

6. Use contexts and labels

Tag changesets with context: prod or labels, then run liquibase update --contexts=prod to control what applies where. This keeps test-only seed data out of production.

Verification

Run liquibase status to list unapplied changesets; it should report none after update. Query DATABASECHANGELOG to confirm the expected rows, and inspect the schema for the new objects.

Next Steps

Generate a baseline changelog from an existing schema with generateChangeLog, add liquibase update to your deploy pipeline, and use diff to detect schema drift between environments.

Prerequisites

  • A relational database
  • Java runtime or Docker
  • Basic SQL knowledge

Steps

  • 1
    Install Liquibase
  • 2
    Create the master changelog
  • 3
    Add a changeset
  • 4
    Apply with update
  • 5
    Roll back a change
  • 6
    Use contexts and labels

Category

Database