You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Ktor+Exposed+MySQL时Flyway版本格式错误排查

问题:Flyway版本格式错误导致数据库迁移失败

问题详情

启用Flyway自动迁移时抛出异常:

FlywayException: Version may only contain 0..9 and . (dot). Invalid version: 1.create.users.table
at org.flywaydb.core.api.MigrationVersion.toBigInteger:271

相关代码文件

迁移文件 src/main/db/migration/V1_create_users_table.kt

package db.migration

import com.coinypal.features.user.UsersTable
import org.flywaydb.core.api.migration.BaseJavaMigration
import org.flywaydb.core.api.migration.Context
import org.jetbrains.exposed.sql.SchemaUtils
import org.jetbrains.exposed.sql.transactions.transaction

class V1_create_users_table : BaseJavaMigration() {
    override fun migrate(context: Context?) {
        transaction{
            SchemaUtils.create(
                UsersTable
            )
        }
    }
}

DbFactory初始化代码

package com.coinypal.config

import com.zaxxer.hikari.HikariConfig
import com.zaxxer.hikari.HikariDataSource
import org.flywaydb.core.Flyway
import org.jetbrains.exposed.sql.Database
import javax.sql.DataSource

object DbFactory {
    fun init(pool: DataSource) {
        Database.connect(pool)
        runFlyway(pool)
    }

    fun init(dbProperties: Env.Datasource) {
        val pool = hikari(dbProperties)
        Database.connect(pool)
        runFlyway(pool)
    }

    private fun hikari(dbProperties: Env.Datasource): HikariDataSource {

        val hikariConfig = HikariConfig().apply {
            jdbcUrl = dbProperties.url
            username = dbProperties.username
            password = dbProperties.password
            driverClassName = dbProperties.driver
        }

        return HikariDataSource(hikariConfig)
    }

    private fun runFlyway(datasource: DataSource) {
        val flyway = Flyway.configure().dataSource(datasource).load()
        try {
            flyway.info()
            flyway.migrate()
        } catch (error: Exception) {
            throw error
        }
    }
}

项目依赖配置

implementation("org.jetbrains.exposed:exposed-core:$exposed_version")
    implementation("org.jetbrains.exposed:exposed-jdbc:$exposed_version")
    implementation("org.jetbrains.exposed:exposed-java-time:$exposed_version") //exposed_version=0.38.2
    implementation("com.zaxxer:HikariCP:$hikariCp_version")
    implementation("org.flywaydb:flyway-core:$flyway_version")
    implementation("org.flywaydb:flyway-mysql:$flyway_version") // flyway_version=8.5.13
    implementation("mysql:mysql-connector-java:8.0.33")

原因分析

Flyway对Java/Kotlin迁移类的命名规则有严格约束:

  • 类名必须遵循V<版本号>__<描述>格式,版本号仅允许包含数字和点,版本号与描述之间必须用双下划线分隔。
  • 当前迁移类名V1_create_users_table使用了单下划线,Flyway会错误地将下划线后的内容解析为版本号的一部分,导致把1.create.users.table识别为版本号,违反了版本号的格式规则。

解决方法

1. 修改迁移类及文件名

将迁移类名从V1_create_users_table改为V1__create_users_table,同时对应的文件名也修改为V1__create_users_table.kt(核心是将版本号与描述之间的单下划线替换为双下划线)。

修改后的迁移类代码:

package db.migration

import com.coinypal.features.user.UsersTable
import org.flywaydb.core.api.migration.BaseJavaMigration
import org.flywaydb.core.api.migration.Context
import org.jetbrains.exposed.sql.SchemaUtils
import org.jetbrains.exposed.sql.transactions.transaction

class V1__create_users_table : BaseJavaMigration() {
    override fun migrate(context: Context?) {
        transaction{
            SchemaUtils.create(
                UsersTable
            )
        }
    }
}

2. 验证扫描路径(可选)

确认Flyway默认扫描路径src/main/db/migration未被修改,当前配置已默认包含该路径,无需额外调整。

内容的提问来源于stack exchange,提问作者Victor Orlyk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 00:42:43