Navicat导出SQL需严格匹配Flyway规范:必须选“结构”或“结构+数据”,禁用“仅数据”;导出后重命名为Vx.x.x__description.sql格式,确保版本号一致、无非法字符;严禁修改已执行脚本,差异变更应使用SQL Preview生成ALTER语句而非全量导出。
navicat 本身不直接集成 flyway,但它能高效生成符合 flyway 命名和内容规范的 sql 脚本——关键在于“怎么导、导什么、怎么改”。用错方式反而会破坏 flyway 的校验机制或导致重复执行。
Navicat 导出 SQL 必须选「仅结构」或「结构+数据」,不能选「仅数据」
Flyway 迁移脚本本质是 DDL(建表、加字段、索引等)+ 可选 DML(INSERT 初始化数据)。Navicat 导出时若只选「仅数据」,生成的 INSERT 语句没有 CREATE TABLE,Flyway 执行会直接报错 Table 'xxx' doesn't exist。
- 正确操作:右键表 → «Dump SQL File» → 勾选 «Structure and Data» 或 «Structure Only»
- 错误操作:勾选 «Data Only»,或导出整个数据库时未取消勾选 «Include DROP statements»(
DROP TABLE会清空已有表,破坏生产环境) - 导出后务必检查首行是否含
CREATE TABLE;若有SET FOREIGN_KEY_CHECKS=0;或USE xxx;,建议手动删掉——Flyway 不依赖库切换,且可能干扰事务边界
导出的 SQL 必须重命名为 Flyway 标准格式 Vx.x.x__description.sql
Flyway 严格按文件名解析版本顺序。Navicat 默认导出名如 cms_user_primary_20260727.sql,直接放 db/migration/ 下会被忽略。
- 命名规则:
V+ 版本号(数字间用点分隔,如1.0.1) +__(两个下划线) + 描述(英文、无空格、用下划线连接) +.sql - 示例:
V1.0.1__create_cms_user_primary_table.sql,不是V1__create_user.sql(版本号位数不一致,后续V1.0.2会被跳过) - 严禁修改已执行脚本的文件名或内容:Flyway 通过 checksum 校验,改动后启动报错
Validate failed: Migration checksum mismatch
Navicat 修改表结构后,必须导出「差异 SQL」而非全量重建
比如给 cms_user_primary 加一列 phone varchar(20),直接导出整张表结构再重命名,会导致 Flyway 把建表语句当成新迁移——而表已存在,执行失败。
- 正确做法:在 Navicat 中右键表 → «Design Table» → 添加字段 → 点击工具栏 «SQL Preview» 按钮,复制生成的
ALTER TABLE ... ADD COLUMN ...语句 - 新建文件,粘贴该语句,保存为
V1.0.2__add_phone_to_user_table.sql - 避免用 Navicat 的 «Synchronize to Database» 功能自动生成同步脚本——它常带
IF NOT EXISTS或条件判断,Flyway 不识别,可能跳过执行
Flyway 启动失败时,别在 Navicat 里手动改表,先查 flyway_schema_history
如果 Navicat 导出的脚本执行出错(比如字段类型冲突),Flyway 会在 flyway_schema_history 表中记录 success = 0。下次启动仍会尝试重试,卡死在该版本。
- 先用 Navicat 连上数据库,查
SELECT * FROM flyway_schema_history ORDER BY installed_on DESC LIMIT 5; - 找到失败那条记录,确认
version和description对应哪个脚本 - 修复脚本内容后,**不要删表或清空历史表**,而是运行
flyway repair(命令行)或在 Spring Boot 中配spring.flyway.repair=true(仅开发环境) - 切忌在 Navicat 里手工执行 ALTER 修复,再删历史记录——这会让 Flyway 失去状态跟踪,后续迁移可能乱序
真正难的不是导出 SQL,而是让 Navicat 的操作意图和 Flyway 的状态机对齐:每一次鼠标点击,都得对应到 flyway_schema_history 里一条不可逆的记录。导出、重命名、验证 checksum、查历史表——漏掉任一环,自动化就变成救火现场。


















