mcpField
F
flyway

flyway

github.com/claude-dev-suite数据与数据库4644 次安装2 天前更新
代码仓库

关于 flyway

为使用 Flyway 管理数据库的开发者提供迁移参考,涵盖 SQL 与 Java 迁移、配置和常见故障处理。

主要功能

  1. 01版本化、可重复迁移命名
  2. 02Spring Boot 配置示例
  3. 03SQL 与 Java 迁移示例
  4. 04Maven 迁移与验证命令
  5. 05常见问题排查建议

适用场景

  1. 01规划数据库架构变更
  2. 02编写数据迁移脚本
  3. 03排查迁移校验或版本错误

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/claude-dev-suite/claude-dev-suite --skill flyway

安装后在 Claude Code 中输入/flyway确认已加载。

详细介绍

Flyway 数据库迁移

深入了解:使用 mcp__documentation__fetch_docs,并将技术指定为:flyway,获取全面的文档。

Maven 配置

<dependency>
    <groupId>org.flywaydb</groupId>
    <artifactId>flyway-core</artifactId>
</dependency>

<dependency>
    <groupId>org.flywaydb</groupId>
    <artifactId>flyway-database-postgresql</artifactId>
</dependency>

<plugin>
    <groupId>org.flywaydb</groupId>
    <artifactId>flyway-maven-plugin</artifactId>
    <version>${flyway.version}</version>
    <configuration>
        <url>jdbc:postgresql://localhost:5432/mydb</url>
        <user>myuser</user>
        <password>mypass</password>
    </configuration>
</plugin>

应用配置

spring:
  flyway:
    enabled: true
    baseline-on-migrate: true
    locations: classpath:db/migration
    validate-on-migrate: true
    out-of-order: false
    clean-disabled: true  # Prevent clean in production!

迁移命名约定

V{version}__{description}.sql   # Versioned migrations
U{version}__{description}.sql   # Undo migrations (Teams/Enterprise)
R__{description}.sql            # Repeatable migrations

示例:

  • V1__create_users_table.sql
  • V1.1__add_email_index.sql
  • V2__create_departments_table.sql
  • R__create_views.sql

初始架构迁移

-- V1__init_schema.sql

-- Users table
CREATE TABLE users (
    id BIGSERIAL PRIMARY KEY,
    name VARCHAR(100) NOT NULL,
    email VARCHAR(255) NOT NULL UNIQUE,
    password VARCHAR(255) NOT NULL,
    role VARCHAR(20) NOT NULL DEFAULT 'USER',
    status VARCHAR(20) NOT NULL DEFAULT 'ACTIVE',
    created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP,
    created_by VARCHAR(255),
    updated_by VARCHAR(255)
);

CREATE INDEX idx_users_email ON users(email);
CREATE INDEX idx_users_status ON users(status);
CREATE INDEX idx_users_role ON users(role);

-- Roles table
CREATE TABLE roles (
    id BIGSERIAL PRIMARY KEY,
    name VARCHAR(50) NOT NULL UNIQUE,
    description VARCHAR(255)
);

-- Insert default roles
INSERT INTO roles (name, description) VALUES
    ('ADMIN', 'System administrator'),
    ('MANAGER', 'Department manager'),
    ('USER', 'Regular user');

添加列的迁移

-- V2__add_phone_to_users.sql

ALTER TABLE users
ADD COLUMN phone VARCHAR(20);

CREATE INDEX idx_users_phone ON users(phone);

添加外键的迁移

-- V3__create_departments.sql

CREATE TABLE departments (
    id BIGSERIAL PRIMARY KEY,
    name VARCHAR(100) NOT NULL UNIQUE,
    code VARCHAR(10) NOT NULL UNIQUE,
    created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);

ALTER TABLE users
ADD COLUMN department_id BIGINT;

ALTER TABLE users
ADD CONSTRAINT fk_users_department
FOREIGN KEY (department_id) REFERENCES departments(id);

CREATE INDEX idx_users_department ON users(department_id);

数据迁移

-- V4__migrate_legacy_data.sql

-- Update existing data
UPDATE users
SET role = 'USER'
WHERE role IS NULL;

-- Migrate data from legacy format
INSERT INTO departments (name, code)
SELECT DISTINCT department_name, UPPER(SUBSTRING(department_name, 1, 3))
FROM legacy_employees
WHERE department_name IS NOT NULL;

可重复迁移(视图)

-- R__create_user_summary_view.sql

DROP VIEW IF EXISTS user_summary;

CREATE VIEW user_summary AS
SELECT
    u.id,
    u.name,
    u.email,
    u.role,
    u.status,
    d.name AS department_name,
    u.created_at
FROM users u
LEFT JOIN departments d ON u.department_id = d.id;

基于 Java 的迁移

@Component
public class V5__ComplexDataMigration implements JavaMigration {

    @Override
    public void migrate(Context context) throws Exception {
        try (Statement stmt = context.getConnection().createStatement()) {
            // Complex migration logic
            ResultSet rs = stmt.executeQuery("SELECT id, data FROM legacy_table");
            while (rs.next()) {
                // Process and migrate data
            }
        }
    }

    @Override
    public Integer getChecksum() { return null; }

    @Override
    public MigrationVersion getVersion() {
        return MigrationVersion.fromVersion("5");
    }

    @Override
    public String getDescription() {
        return "Complex data migration";
    }
}

用于日志记录的回调

@Component
public class FlywayCallback implements Callback {

    private static final Logger log = LoggerFactory.getLogger(FlywayCallback.class);

    @Override
    public boolean supports(Event event, Context context) {
        return event == Event.AFTER_EACH_MIGRATE ||
               event == Event.AFTER_MIGRATE_ERROR;
    }

    @Override
    public boolean canHandleInTransaction(Event event, Context context) {
        return true;
    }

    @Override
    public void handle(Event event, Context context) {
        if (event == Event.AFTER_EACH_MIGRATE) {
            MigrationInfo info = context.getMigrationInfo();
            log.info("Migrated: {} - {} ({}ms)",
                info.getVersion(),
                info.getDescription(),
                info.getExecutionTime());
        } else if (event == Event.AFTER_MIGRATE_ERROR) {
            log.error("Migration failed!");
        }
    }

    @Override
    public String getCallbackName() {
        return "LoggingCallback";
    }
}

Maven 命令

# Run migrations
mvn flyway:migrate

# Show migration info
mvn flyway:info

# Validate migrations
mvn flyway:validate

# Repair checksum mismatches
mvn flyway:repair

# Clean database (careful!)
mvn flyway:clean

# Baseline existing database
mvn flyway:baseline

最佳实践

实践说明
切勿编辑已应用的迁移改为创建新的迁移
测试迁移在测试中使用 H2
迁移前备份尤其是在生产环境中
使用事务将 DDL 包装在事务中
版本控制将迁移文件保存在 Git 中
命名约定使用描述性名称

不应使用此技能的情况

  • 通用迁移策略 - 使用 migrations 技能了解相关概念
  • Liquibase - 使用 Liquibase 专属文档
  • Prisma 迁移 - 使用 prisma 技能
  • TypeORM 迁移 - 使用 typeorm 技能

反模式

反模式问题解决方案
修改已应用的迁移校验和验证失败改为创建新的迁移
现有数据库未设置基线迁移时失败使用 baseline-on-migrate: true
在 SQL 迁移中编写复杂逻辑难以测试和调试使用基于 Java 的迁移
忽略验证各环境之间不一致部署前始终进行验证
在生产环境中设置 clean-disabled: false有数据丢失风险在生产环境中始终禁用 clean
迁移顺序错乱版本冲突使用连续的版本号

快速故障排除

问题诊断修复方法
校验和不匹配将文件与 flyway_schema_history 对比使用 flyway repair 或创建新的迁移
迁移顺序错误检查版本号修正版本号,或设置 out-of-order: true
迁移失败检查 flyway_schema_history.success修复问题后重试
缺少迁移检查 locations 配置验证 classpath:db/migration 路径
基线冲突检查 baseline-version设置正确的基线版本

参考文档

评论

支持 Markdown