如何拆分changelog.yaml为子部分?求databaseChangeLog拆分加载示例
Hey Dieter, great question! Let's break this down step by step since you've got two related but distinct goals here—splitting your root changelog into logical subsections, and extracting individual change sets to their own files that you can reload using either FileSystemAccessor or ClassPathAccessor.
First, you can organize your main changelog into logical subsections (like per feature, module, or release) using Liquibase's include directive. This keeps your root file clean and makes it easier to manage changes across different parts of your application.
Example Root changelog.yaml
databaseChangeLog: # Include feature-specific sub-changelogs - include: file: changelogs/features/user-management.yaml relativeToChangelogFile: true resourceAccessor: liquibase.resource.FileSystemAccessor - include: file: changelogs/features/product-catalog.yaml relativeToChangelogFile: true resourceAccessor: liquibase.resource.FileSystemAccessor # Include release-specific sub-changelogs (using ClassPathAccessor) - include: file: changelogs/releases/v1.0.0.yaml relativeToChangelogFile: true resourceAccessor: liquibase.resource.ClassPathAccessor
relativeToChangelogFile: true: Ensures file paths are resolved relative to the root changelog's location—this is critical for reliable loading withFileSystemAccessor.resourceAccessor: Explicitly defines which accessor to use. You can omit this if you want Liquibase to auto-detect, but setting it explicitly gives you full control for reload scenarios.
If you want every single changeSet in its own dedicated YAML file, you can go a level deeper with your organization. Here's how to set this up:
Step 1: Create Individual Change Set Files
Each change (like creating a table, adding a column) gets its own file. For example:
changelogs/features/user-management/create-users-table.yaml:
databaseChangeLog: - changeSet: id: "create-users-table-1.0" author: "dieter" changes: - createTable: tableName: users columns: - column: name: id type: BIGINT autoIncrement: true constraints: primaryKey: true nullable: false - column: name: email type: VARCHAR(255) constraints: nullable: false unique: true
changelogs/features/user-management/add-user-created-at.yaml:
databaseChangeLog: - changeSet: id: "add-user-created-at-1.0" author: "dieter" changes: - addColumn: tableName: users columns: - column: name: created_at type: TIMESTAMP defaultValueComputed: CURRENT_TIMESTAMP constraints: nullable: false
Step 2: Group Changes in a Subsection Changelog
Create a parent file for each feature/module to include all its individual change files. For example changelogs/features/user-management.yaml:
databaseChangeLog: - include: file: create-users-table.yaml relativeToChangelogFile: true resourceAccessor: liquibase.resource.FileSystemAccessor - include: file: add-user-created-at.yaml relativeToChangelogFile: true resourceAccessor: liquibase.resource.FileSystemAccessor
Step 3: Reloading with FileSystemAccessor or ClassPathAccessor
When you need to reload these changelogs (e.g., during active development or dynamic application updates), here's how to ensure Liquibase uses the right accessor:
Using FileSystemAccessor
Perfect for changelogs stored on your local filesystem (not packaged in a JAR/WAR). You can configure this via command line or Liquibase properties:
Command Line Example:
liquibase update \ --changeLogFile=changelog.yaml \ --resourceAccessor=liquibase.resource.FileSystemAccessor
Liquibase Properties File:
changeLogFile: changelog.yaml resourceAccessor: liquibase.resource.FileSystemAccessor
Using ClassPathAccessor
Use this if your changelogs are packaged in your application's classpath (e.g., in src/main/resources). Liquibase will auto-detect classpath resources, but you can explicitly set the accessor for clarity:
Command Line Example:
liquibase update \ --changeLogFile=classpath:changelog.yaml \ --resourceAccessor=liquibase.resource.ClassPathAccessor
Liquibase Properties File:
changeLogFile: classpath:changelog.yaml resourceAccessor: liquibase.resource.ClassPathAccessor
Programmatic Reload (For Dynamic Apps)
If you need to reload changelogs programmatically in a running application, you can instantiate the accessors directly:
// FileSystemAccessor example FileSystemAccessor fileAccessor = new FileSystemAccessor(); DatabaseChangeLog changelog = new DatabaseChangeLog("/path/to/your/changelog.yaml", fileAccessor, liquibaseInstance); // ClassPathAccessor example ClassPathAccessor classPathAccessor = new ClassPathAccessor(); DatabaseChangeLog changelog = new DatabaseChangeLog("classpath:changelog.yaml", classPathAccessor, liquibaseInstance);
内容的提问来源于stack exchange,提问作者Dieter

