golang-migrate
migrate 是一个用go写的数据库迁移工具,提供CLI和导入库两种方式,支持的数据库有MySQL,PostgreSQL,SQLite,MongoDB等。
使用migrate数据库迁移工具可以在更新的时候避免一些因手动操作导致的意外事故,提高更新流程的集成度。
migrate CLI#
安装#
MacOS或者Windows可以通过软件包下载
MacOS
1 | brew install golang-migrate |
Windows
1 | scoop install migrate |
Linux从这里 Release Downloads 下载工具包,解压即可使用。
常用的迁移命令#
创建sql文件#
1 | migrate create -ext sql -dir ./sit106/sql -seq create_test_table |
create命令会创建两个空sql文件,一个名字带up,表示升级文件,一个名字带down,表示回滚文件,文件名带有顺序的版本号和指定的文件名。
升级 N 个版本#
1 | migrate -path ./sit106/sql -database 'mysql://root:123456@tcp(127.0.0.1:3306)/test?query' up [N] |
1 | ## 第一次执行up命令后,会自动创建 schema_migrations 表,记录迁移版本号和状态。 |
每一次执行迁移命令,会首先从 schema_migrations 表获取版本号,再从指定目录获取比当前版本号要高的迁移的文件,再执行迁移。
注意: 不加参数 N ,则更新到最新,默认不加。
降级 N 个版本#
1 | migrate -path ./sit106/sql -database 'mysql://root:123456@tcp(127.0.0.1:3306)/test?query' down [N] |
注意: 不加参数 N ,则回滚到版本0。
忽略第 N 版本的脏状态 dirty state#
1 | migrate -path ./sit106/sql -database 'mysql://root:123456@tcp(127.0.0.1:3306)/test?query' force N |
当升级或者回滚的sql脚本出现错误,当前版本会被标记为脏状态,无法继续更新或者回滚。
在修正sql脚本的错误后,需要使用次命令,清除脏状态,方可以继续升级或者回滚。
查看当前迁移版本#
1 | migrate -path ./sit106/sql -database 'mysql://root:123456@tcp(127.0.0.1:3306)/test?query' version |
跳跃到第 N 个版本#
1 | migrate -database 'mysql://root:123456@tcp(127.0.0.1:3306)/test?query' goto N |
按顺序升级或者回滚到指定版本。
更多用法通过帮助获取#
1 | migrate |
以上命令的 path 参数的写法-path ./sit106/sql
是一个简写的方式,原型写法为
1 | 仅当从文件系统加载配置的时候,可以使用简写方式。 |
example migration.go#
1 | package migration |
从以上代码可以看出,当up命令发生错误时,需要执行down命令,但是具体down几个版本,则需要自己控制参数。
扩展建议#
可新增一个字段pre_version,记录上一个版本号。
1 | CREATE TABLE `schema_migrations` ( |
当执行up命令前,记录当前的版本号version,执行up命令后,得到new_version,最后更新schema_migrations表。
1 | set pre_version=version,version=new_version |
当执行down命令时,首先取pre_version的值,回滚版本后,更新后执行。
1 | set version=pre_version |
这样至少可以回滚到上一个版本。
需要注意的事#
冲突#
在一个多人开发的项目中,难免会遇到冲突,所以在代码审查的时候要尤其注意。
幂等#
尽量让你的迁移时幂等的——连续两次运行相同的sql语句得到相同的结果,这会让迁移代码更加健壮。例如使用CREATE TABLE IF NOT EXISTS
代替CREATE TABLE
事务#
如果一次迁移中有多个命令/查询,最好把它们包在一个事务中,这样,当其中一个命令失败,我们的数据库将保持不变。