golang实现PostgreSQL数据库迁移管理插件库go-pg-migrations的使用
go-pg-migrations 使用指南
go-pg-migrations 是一个用于在 Go 语言中管理 PostgreSQL 数据库迁移的库,基于 go-pg/pg 库构建。
安装
由于 go-pg 现在支持 Go 模块,go-pg-migrations 也支持模块。它目前依赖于 go-pg 的 v10 版本。在带有 go.mod 的项目中使用以下命令安装:
$ go get github.com/robinjoseph08/go-pg-migrations/v3
如果你还没有使用 Go 模块,仍然可以使用该包的 v1 版本。
使用示例
基本用法
创建一个 main 包(例如 example),调用 migrations.Run 并传入迁移文件保存目录、*pg.DB 实例和 os.Args:
package main
import (
"log"
"os"
"github.com/go-pg/pg/v10"
"github.com/robinjoseph08/go-pg-migrations/v3"
)
func main() {
db := pg.Connect(&pg.Options{
Addr: "localhost:5432",
User: "postgres",
Password: "postgres",
Database: "test",
})
err := migrations.Run(db, "example", os.Args)
if err != nil {
log.Fatalln(err)
}
}
命令示例
创建迁移文件:
$ go run example/*.go create create_users_table
Creating example/20180812001528_create_users_table.go...
运行迁移:
$ go run example/*.go migrate
Running batch 1 with 1 migration(s)...
Finished running "20180812001528_create_users_table"
查看迁移状态:
$ go run example/*.go status
+---------+-----------------------------------+-------+
| Applied | Migration | Batch |
+---------+-----------------------------------+-------+
| √ | 20180812001528_create_users_table | 1 |
+---------+-----------------------------------+-------+
回滚迁移:
$ go run example/*.go rollback
Rolling back batch 1 with 1 migration(s)...
Finished rolling back "20180812001528_create_users_table"
获取帮助:
$ go run example/*.go help
Usage:
go run example/*.go [command]
Commands:
create - create a new migration in example with the provided name
migrate - run any migrations that haven't been run yet
rollback - roll back the previous run batch of migrations
status - show the status of each migration
help - print this help text
Examples:
go run example/*.go create create_users_table
go run example/*.go migrate
go run example/*.go rollback
go run example/*.go status
go run example/*.go help
迁移文件示例
创建迁移文件时会生成如下模板:
package example
import (
"github.com/go-pg/pg/v10"
"github.com/go-pg/pg/v10/orm"
migrations "github.com/robinjoseph08/go-pg-migrations/v3"
)
func init() {
up := func(db orm.DB) error {
_, err := db.Exec("")
return err
}
down := func(db orm.DB) error {
_, err := db.Exec("")
return err
}
opts := migrations.MigrationOptions{}
migrations.Register("20180812001528_create_users_table", up, down, opts)
}
生产环境部署
在生产环境中,可以编译单独的迁移二进制文件并部署:
# Dockerfile
FROM golang:1.13.3 as build
WORKDIR /app
COPY go.mod go.mod
COPY go.sum go.sum
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -installsuffix cgo -ldflags '-w -s' -o ./bin/serve ./cmd/serve
RUN CGO_ENABLED=0 GOOS=linux go build -installsuffix cgo -ldflags '-w -s' -o ./bin/migrations ./cmd/migrations
FROM alpine:3.8
RUN apk --no-cache add ca-certificates
COPY --from=build /app/bin /bin
CMD ["serve"]
构建并运行迁移:
$ docker build -t service:latest .
$ docker run --rm service:latest migrations migrate
特性
- 完整的迁移差异检查,确保不会遗漏任何迁移
- 基于时间戳的前缀,防止不同分支上的迁移版本冲突
- 可选择在事务中运行迁移
- 迁移锁定机制,防止并发迁移
- 批处理级别的回滚功能
- 明确的推荐工作流程
相比 go-pg/migrations,go-pg-migrations 提供了更健壮和安全的迁移体验。
更多关于golang实现PostgreSQL数据库迁移管理插件库go-pg-migrations的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
更多关于golang实现PostgreSQL数据库迁移管理插件库go-pg-migrations的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
使用go-pg-migrations实现PostgreSQL数据库迁移管理
go-pg-migrations是一个基于go-pg库的PostgreSQL数据库迁移管理工具,它可以帮助你轻松管理数据库schema的版本变更。下面我将详细介绍如何使用这个库。
安装
首先安装go-pg-migrations和依赖的go-pg库:
go get github.com/go-pg/migrations/v8
go get github.com/go-pg/pg/v10
基本用法
1. 创建迁移文件
迁移文件需要放在特定目录下,通常命名为migrations
。每个迁移文件命名格式为:[版本号]_[描述].up.sql
和[版本号]_[描述].down.sql
。
例如:
migrations/001_init.up.sql
- 初始化数据库migrations/001_init.down.sql
- 回滚初始化
2. 初始化迁移器
package main
import (
"log"
"os"
"github.com/go-pg/migrations/v8"
"github.com/go-pg/pg/v10"
)
func main() {
db := pg.Connect(&pg.Options{
Addr: "localhost:5432",
User: "postgres",
Password: "password",
Database: "mydb",
})
defer db.Close()
// 创建迁移器
migrator := migrations.NewCollector()
// 从文件系统加载迁移
err := migrator.DiscoverSQLMigrations("migrations")
if err != nil {
log.Fatal(err)
}
// 运行迁移命令
oldVersion, newVersion, err := migrator.Run(db, os.Args[1:]...)
if err != nil {
log.Fatal(err)
}
if newVersion != oldVersion {
log.Printf("migrated from version %d to %d\n", oldVersion, newVersion)
} else {
log.Printf("version is %d\n", oldVersion)
}
}
常用命令
编译上述代码后,可以通过命令行参数执行不同操作:
# 初始化迁移表
./migrator init
# 查看当前版本
./migrator version
# 升级到最新版本
./migrator up
# 升级到特定版本
./migrator up 2
# 回滚一个版本
./migrator down
# 回滚到特定版本
./migrator down 1
# 重置数据库(所有down迁移)
./migrator reset
迁移文件示例
001_init.up.sql
CREATE TABLE users (
id SERIAL PRIMARY KEY,
name TEXT NOT NULL,
email TEXT UNIQUE NOT NULL,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
CREATE TABLE posts (
id SERIAL PRIMARY KEY,
user_id INTEGER REFERENCES users(id),
title TEXT NOT NULL,
body TEXT,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
001_init.down.sql
DROP TABLE posts;
DROP TABLE users;
002_add_user_status.up.sql
ALTER TABLE users ADD COLUMN status TEXT DEFAULT 'active';
002_add_user_status.down.sql
ALTER TABLE users DROP COLUMN status;
使用Go代码定义迁移
除了SQL文件,你也可以用Go代码定义迁移:
func init() {
migrations.Register(func(db migrations.DB) error {
_, err := db.Exec(`
CREATE TABLE products (
id SERIAL PRIMARY KEY,
name TEXT NOT NULL,
price DECIMAL(10,2) NOT NULL
)
`)
return err
}, func(db migrations.DB) error {
_, err := db.Exec("DROP TABLE products")
return err
})
}
高级用法
事务性迁移
默认情况下,每个迁移都在单独的事务中执行。你可以禁用此行为:
migrator.SetTableName("my_migrations") // 自定义迁移表名
migrator.DisableSQLMigrations() // 禁用SQL迁移
migrator.DisableTx() // 禁用事务
自定义日志
migrator.SetLogger(logger) // 实现migrations.Logger接口
集成到现有项目
在实际项目中,你可以将迁移逻辑封装成单独的命令:
// cmd/migrate/main.go
package main
import (
"log"
"os"
"github.com/go-pg/migrations/v8"
"github.com/go-pg/pg/v10"
"github.com/yourproject/internal/db"
)
func main() {
migrator := migrations.NewCollector()
err := migrator.DiscoverSQLMigrations("migrations")
if err != nil {
log.Fatal(err)
}
_, _, err = migrator.Run(db.GetDB(), os.Args[1:]...)
if err != nil {
log.Fatal(err)
}
}
最佳实践
- 每个迁移文件只做一件事
- 确保down迁移能正确回滚up迁移的操作
- 在生产环境执行迁移前,先在测试环境验证
- 考虑使用版本控制来管理迁移文件
- 对于大型数据库,考虑将数据迁移与结构迁移分开
go-pg-migrations提供了一种简单而强大的方式来管理PostgreSQL数据库的变更,特别适合与go-pg/pg库一起使用。通过遵循上述模式,你可以轻松实现数据库的版本控制和团队协作。