Spring应用中Flyway V1.1迁移脚本未执行原因咨询
让我来帮你分析一下这个问题——你的Flyway脚本没执行,核心线索其实在日志里:Current version of schema "DB2INST1": 1 以及 Schema "DB2INST1" is up to date. No migration necessary.,结合你的多schema配置,这里有几个可能的原因,我一个个给你拆解:
1. 脚本没明确指定目标Schema(SRVO)
你配置了两个Schema:DB2INST1, SRVO,Flyway默认会把第一个Schema(DB2INST1)作为版本跟踪的主Schema,flyway_schema_history表就建在这里。如果你的迁移脚本里没有明确写CREATE TABLE SRVO.你的表名(...),Flyway会默认用连接的默认Schema(日志里显示Default schema: null,实际可能是DB2INST1)去执行脚本。
如果DB2INST1里已经有你要创建的表(属于基线标记的现有数据库状态),Flyway会认为这个变更已经在基线里了,自然不会执行。
解决办法:
在脚本里明确指定SRVO Schema:
CREATE TABLE SRVO.你的表名 ( -- 表结构定义 );
2. 默认Schema未配置,导致执行上下文混乱
日志里显示Default schema: null,这意味着Flyway在执行脚本时没有明确的默认Schema上下文,可能导致它无法确定该在哪个Schema执行你的脚本,进而跳过执行。
解决办法:
在你的flywayConfig Bean里添加defaultSchema属性,指定为SRVO:
<bean id="flywayConfig" class="org.flywaydb.core.api.configuration.ClassicConfiguration"> <!-- 已有的其他属性 --> <property name="defaultSchema" value="SRVO"/> </bean>
这样Flyway会默认在SRVO Schema下执行所有迁移脚本,确保表创建在正确的位置。
3. 基线未覆盖SRVO Schema,导致Flyway误判变更已存在
你开启了baselineOnMigrate=true,Flyway会把现有数据库的状态标记为基线版本1,但默认情况下它只会扫描第一个Schema(DB2INST1)的现有对象。如果你的脚本是创建一个已经存在的表,Flyway会验证通过但不执行;如果是新表,那这个原因不成立,但可以通过配置让基线覆盖两个Schema。
解决办法:
如果需要基线化两个Schema的现有对象,添加baselineSchemas属性:
<property name="baselineSchemas" value="DB2INST1,SRVO"/>
这样Flyway在基线时会扫描两个Schema的所有对象,后续迁移只会执行真正的新增变更。
4. 版本号识别异常(少见但值得排查)
虽然V1.1__create.sql是合法的Flyway版本命名,但某些旧版本的Flyway可能对带点的版本号处理有问题。你可以尝试把脚本重命名为V1_1__create.sql(用下划线代替点),或者V1.0.1__create.sql,看看Flyway是否能识别为更高版本的迁移。
最后一招:开DEBUG日志看细节
当前的INFO日志信息不够全,你可以把Flyway的日志级别调到DEBUG,这样能看到脚本是否被加载、是否尝试执行、执行时的SQL语句等细节,帮你精准定位问题。在Spring的日志配置里添加:
<logger name="org.flywaydb" level="DEBUG"/>
按这个顺序排查,应该很快能解决问题!
内容的提问来源于stack exchange,提问作者ka3ak

