golang简单易用的数据库迁移插件库migrator的使用
Golang简单易用的数据库迁移插件库migrator的使用
migrator是一个极其简单的Go数据库迁移库。
特性
- 代码简单
- 可作为库使用,可嵌入和扩展
- 支持所有
database/sql
兼容的数据库 - 支持Go代码迁移,可以是事务性的(
migrator.Migration
)或非事务性的(migrator.MigrationNoTx
) - 不需要使用
//go:embed
,因为所有迁移都是Go代码
兼容性
虽然任何支持database/sql
及其推荐驱动程序的数据库都应该可以正常工作,但目前仅明确测试了PostgreSQL
和MySQL
。
使用示例
以下示例假设:
- 有一个工作的
postgres
数据库连接在localhost上,用户名为postgres
,密码为空,数据库名为foo
快速开始
package main
import (
"database/sql"
"log"
_ "github.com/jackc/pgx/v4/stdlib" // postgres驱动
"github.com/lopezator/migrator"
)
func main() {
// 配置迁移
m, err := migrator.New(
migrator.Migrations(
&migrator.Migration{
Name: "Create table foo",
Func: func(tx *sql.Tx) error {
if _, err := tx.Exec("CREATE TABLE foo (id INT PRIMARY KEY)"); err != nil {
return err
}
return nil
},
},
),
)
if err != nil {
log.Fatal(err)
}
// 打开数据库连接
db, err := sql.Open("pgx", "postgres://postgres@localhost/foo?sslmode=disable")
if err != nil {
log.Fatal(err)
}
// 执行迁移
if err := m.Migrate(db); err != nil {
log.Fatal(err)
}
}
注意事项:
- migrator创建/管理一个名为
migrations
的表来跟踪应用的版本。如果你想自定义表名,可以将migrator.TableName("my_migrations")
作为额外选项传递给migrator.New
函数。
日志记录
默认情况下,migrator将应用/已应用的迁移信息打印到stdout。如果你需要特殊格式或想使用第三方日志库,可以使用WithLogger
选项:
logger := migrator.WithLogger(migrator.LoggerFunc(func(msg string, args ...interface{}) {
// 你的日志代码
}))
然后你只需要将logger作为选项传递给migrator.New
。
更多示例
可以查看migrator_test.go文件获取更多示例。
不想在字符串中写复杂的迁移?
你仍然可以使用你喜欢的嵌入工具将迁移写在.sql
文件中,然后加载到migrator中!
迁移顺序
为了避免不同标识符、ID冲突等问题,迁移的顺序就是传递给migrator的顺序。
没有回滚迁移?
添加回滚迁移的功能会增加API、代码的复杂性,并增加失去迁移列表与数据库当前状态同步的风险。此外,在某些情况下,并非所有迁移都可以轻松回滚或根本无法回滚。
我们建议遵循数据库迁移的"仅追加"哲学,因此纠正有缺陷的迁移是通过添加新迁移而不是回滚它来实现的。
注意事项
- 迁移名称必须对你的数据库引擎是SQL安全的。建议避免使用冲突字符,如
'
,否则你将不得不自己转义它们,例如PostgreSQL使用''
,MySQL使用\'
。
动机
为什么需要另一个迁移库?
- 轻量级实现,仅支持
database/sql
。Migrator不需要任何ORM或其他重型库作为依赖。它只是一个单文件,不到200行代码! - 易于嵌入到你的应用程序中,不需要安装/使用单独的二进制文件
- 支持Go迁移,可以是事务性的或非事务性的
- 灵活使用
这不是migrator的目标
- 添加对
database/sql
之外的数据库的支持 - 为了添加可以在用户端轻松实现的功能而使代码/逻辑复杂化,如查看当前版本、已应用版本列表等
- 添加一堆依赖项只是为了提供CLI/独立功能
贡献
欢迎提交Pull Request,这是一个早期实现,所有领域都需要工作:文档、示例、测试、CI…
最简单的方法是安装docker和docker-compose,并确保在提交PR之前运行以下命令以符合代码标准并通过所有测试:
$> docker-compose up -d --build
$> docker-compose exec migrator make prepare
$> docker-compose exec migrator make sanity-check
$> docker-compose exec migrator make test
$> docker-compose down
Logo
Logo来自@ashleymcnamara的gophers仓库。我只是对它做了轻微的修改。
更多关于golang简单易用的数据库迁移插件库migrator的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
更多关于golang简单易用的数据库迁移插件库migrator的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
Golang数据库迁移插件库migrator使用指南
migrator是一个简单易用的Golang数据库迁移工具库,它支持多种数据库,提供了简洁的API来管理数据库结构变更。下面我将详细介绍如何使用migrator进行数据库迁移。
安装
首先安装migrator库:
go get -u github.com/golang-migrate/migrate/v4
根据你使用的数据库,还需要安装对应的驱动:
# PostgreSQL
go get -u github.com/golang-migrate/migrate/v4/database/postgres
go get -u github.com/lib/pq
# MySQL
go get -u github.com/golang-migrate/migrate/v4/database/mysql
go get -u github.com/go-sql-driver/mysql
# SQLite
go get -u github.com/golang-migrate/migrate/v4/database/sqlite3
基本使用
1. 初始化迁移
首先创建迁移文件目录,通常命名为migrations
。在该目录下创建迁移文件,命名格式为<version>_<name>.up.sql
和<version>_<name>.down.sql
。
例如:
0001_create_users_table.up.sql
0001_create_users_table.down.sql
2. 编写迁移文件
up.sql
文件包含要执行的SQL语句,down.sql
包含回滚操作。
示例0001_create_users_table.up.sql
:
CREATE TABLE users (
id SERIAL PRIMARY KEY,
name VARCHAR(255) NOT NULL,
email VARCHAR(255) UNIQUE NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
对应的0001_create_users_table.down.sql
:
DROP TABLE IF EXISTS users;
3. 在Go代码中使用
package main
import (
"database/sql"
"log"
"github.com/golang-migrate/migrate/v4"
"github.com/golang-migrate/migrate/v4/database/postgres"
_ "github.com/golang-migrate/migrate/v4/source/file"
_ "github.com/lib/pq"
)
func main() {
// 初始化数据库连接
db, err := sql.Open("postgres", "postgres://user:password@localhost:5432/dbname?sslmode=disable")
if err != nil {
log.Fatal(err)
}
defer db.Close()
// 创建数据库驱动实例
driver, err := postgres.WithInstance(db, &postgres.Config{})
if err != nil {
log.Fatal(err)
}
// 创建migrate实例
m, err := migrate.NewWithDatabaseInstance(
"file://migrations",
"postgres", driver)
if err != nil {
log.Fatal(err)
}
// 执行迁移
err = m.Up()
if err != nil && err != migrate.ErrNoChange {
log.Fatal(err)
}
log.Println("Migration done")
}
常用操作
执行特定数量的迁移
// 执行2个迁移
err = m.Steps(2)
if err != nil {
log.Fatal(err)
}
回滚迁移
// 回滚1个迁移
err = m.Steps(-1)
if err != nil {
log.Fatal(err)
}
// 回滚所有迁移
err = m.Down()
if err != nil {
log.Fatal(err)
}
强制版本号
当迁移出现问题时,可以强制设置版本号:
err = m.Force(2) // 强制设置为版本2
if err != nil {
log.Fatal(err)
}
最佳实践
- 版本控制:将迁移文件纳入版本控制系统
- 原子性:每个迁移应该是原子的,要么完全成功,要么完全失败
- 可逆性:每个迁移都应该有对应的回滚操作
- 测试:在生产环境使用前,先在测试环境测试迁移
- 备份:执行重要迁移前备份数据库
高级特性
使用Go代码作为迁移
除了SQL文件,migrator还支持用Go代码编写迁移:
// 创建迁移文件
migrate.Create("migrations", "create_users_table")
// 生成的go文件示例
func Up(tx *sql.Tx) error {
_, err := tx.Exec("CREATE TABLE users (id SERIAL PRIMARY KEY, name VARCHAR(255))")
return err
}
func Down(tx *sql.Tx) error {
_, err := tx.Exec("DROP TABLE users")
return err
}
使用不同的源
除了文件系统,migrator还支持从其他源读取迁移:
// 从GitHub读取
m, err := migrate.New(
"github://owner/repo/path/to/migrations#ref",
"postgres://user:password@localhost:5432/database?sslmode=disable")
总结
migrator是一个功能强大且灵活的数据库迁移工具,通过简单的API和文件结构,可以轻松管理数据库的版本变更。它的主要优点包括:
- 支持多种数据库
- 简单易用的命令行和API
- 支持SQL和Go代码两种迁移方式
- 完善的版本控制和回滚机制
通过合理使用migrator,可以大大简化数据库结构变更的管理工作,提高开发效率。