golang-migrate cli 需单独安装并配置 path;迁移文件须严格命名如 000001_init.up.sql;go 代码中需显式导入驱动包;url 密码需转义;上线前必须执行 validate 和 version 校验。

golang-migrate 命令行工具必须先装好
没装 migrate CLI,go run 或代码里调用 migrate.Up 都会失败——它不依赖 Go 包自动带命令行,得单独装。Mac 用户容易误以为 go install github.com/golang-migrate/migrate/v4/cmd/migrate@latest 就够了,但新版默认不加 $GOPATH/bin 到 $PATH,运行 migrate -version 会报 command not found。
实操建议:
- 确认安装路径:
go install github.com/golang-migrate/migrate/v4/cmd/migrate@latest后,查go env GOPATH,把bin加进$PATH - Windows 用户直接用
choco install migrate更稳,避免 Go 模块路径解析问题 - 别用
docker run --rm -v $(pwd):/migrations migrate/migrate临时跑——挂载路径权限、驱动名大小写(比如postgres不能写成Postgres)容易出错
迁移文件命名必须严格匹配 数字_描述.up.sql 和 .down.sql
migrate 不识别任意文件名,也不接受 .sql 外的后缀(比如 .pgsql)。常见错误是手动生成文件时写成 20240501_create_users.sql,漏掉 .up,结果执行 migrate -path ./migrations -database "..." up 时静默跳过,表根本没建。
实操建议:
- 用
migrate create -ext sql -dir ./migrations -seq init生成,它自动输出000001_init.up.sql和.down.sql -
-seq生成递增序号,-ts用时间戳(如20240501123045),选哪个取决于团队偏好,但别混用 -
.down.sql不是可选——哪怕你暂时不回滚,也得留空或写DROP TABLE IF EXISTS xxx;,否则migrate down直接报错
Go 代码里调用 migrate.New 要注意驱动注册和 URL 格式
直接传 "postgres://..." 给 migrate.New 会 panic:`unknown driver "postgres" (forgotten import?)`。因为 golang-migrate 的驱动是解耦的,必须显式导入对应驱动包并触发 init() 注册。
实操建议:
- 导入驱动:对 PostgreSQL,加
_ "github.com/golang-migrate/migrate/v4/database/postgres";SQLite 用sqlite3包,MySQL 用mysql包——名字必须跟 URL scheme 一致 - 数据库 URL 中的参数要转义:密码含
@或/时,必须用url.QueryEscape处理,否则解析失败 - 别在测试中复用同一
*migrate.Migrate实例多次调用Up——它内部维护状态,第二次会报no change,应每次新建或重置
生产环境执行前必须验证 dry-run 和版本锁
migrate 默认不校验当前 DB 版本是否与迁移文件匹配,上线时如果本地开发多跑了几个 up,而生产库还卡在旧版本,直接 up 可能跳过中间步骤,导致 Schema 错乱。
实操建议:
- 上线前跑
migrate -path ./migrations -database "..." version确认目标库当前版本 - 用
migrate -path ./migrations -database "..." force 20240501123045强制设为某版本(仅调试用),但生产严禁用 - CI/CD 流程里加
migrate -path ./migrations -database "..." validate,它会检查 SQL 语法、文件名连续性、up/down 成对性——这个命令常被跳过,却是防人为失误的最后一道坎
最麻烦的不是语法错,是跨环境时 migration 文件被 Git 换行符污染(尤其是 Windows 提交、Linux 执行),.up.sql 末尾多一个 \r,PostgreSQL 解析就挂。验证阶段发现不了,得靠 file migration/*.up.sql 看编码和换行符。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











