使用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
相关产品推荐
相关产品推荐

