Use preconditions with modifyChangeSets for multi-platform changelogs

Last updated: June 9, 2026

This procedure configures preconditions within modifyChangeSets blocks so that Liquibase skips changesets intended for a different database platform. This lets teams maintain a single changelog repository for all database platforms without adding dbms attributes to every individual changeset.

Important: Do not use changelog-level preConditions (outside of changesets) in included files to control per-changeset execution. Changelog-level preconditions are evaluated during validation, not during changeset execution, so onFail=CONTINUE causes a ValidationFailedException instead of skipping changesets. Use modifyChangeSets preconditions instead.

How it works

When you add a preConditions element inside a modifyChangeSets block, Liquibase applies that precondition to every changeset included within the block. This happens at the changeset level, so onFail and onError behaviors (CONTINUE, HALT, WARN, MARK_RAN) work exactly as they do for changeset-level preconditions.

  • If a changeset already has its own preConditions, the modifyChangeSets precondition is not applied to that changeset. The changeset-level precondition takes priority.

  • Changesets outside modifyChangeSets blocks are not affected.

  • All precondition types are supported: dbms, tableExists, runningAs, sqlCheck, and others.

Before you begin

  • Identify which database platforms your changelogs target (for example, oracle, postgresql, mysql, mssql, and others).

  • Organize your changelogs so that platform-specific changesets are in separate files that can be wrapped in modifyChangeSets blocks.

Procedure

Step 1: Create platform-specific changelog files

Create separate changelog files for each database platform. These files contain regular changesets without any preconditions.

oracle-changes

loading

loading

loading

postgresql-changes

loading

loading

loading

Step 2: Create a root changelog with modifyChangeSets preconditions

Wrap each platform-specific include in a modifyChangeSets block with a preConditions element. Changesets that apply to all platforms go outside modifyChangeSets blocks.

Root changelog

loading

loading

loading

Step 3: Use includeAll for directory-based organization (optional)

You can use includeAll instead of include to include all changelog files in a directory.

includeAll

loading

loading

loading

Step 4: Run Liquibase

Run Liquibase against any target database. Changesets for non-matching platforms are automatically skipped.

liquibase --changelog-file=root-changelog.xml update

Related links