golang数据库迁移管理工具插件goose的使用
Golang数据库迁移管理工具插件Goose的使用
Goose是一个数据库迁移工具,既可以作为CLI使用,也可以作为库集成到Go应用中。
安装
go install github.com/pressly/goose/v3/cmd/goose@latest
对于macOS用户,也可以通过Homebrew安装:
brew install goose
基本使用
创建迁移文件
# 创建SQL迁移文件
$ goose create add_some_column sql
$ Created new file: 20170506082420_add_some_column.sql
# 使用顺序编号创建迁移文件
$ goose -s create add_some_column sql
$ Created new file: 00001_add_some_column.sql
# 创建Go迁移文件
$ goose create fetch_user_data go
$ Created new file: 20170506082421_fetch_user_data.go
应用迁移
# 应用所有可用迁移
$ goose up
$ OK 001_basics.sql
$ OK 002_next.sql
$ OK 003_and_again.go
# 迁移到特定版本
$ goose up-to 20170506082420
$ OK 20170506082420_create_table.sql
# 应用单个迁移
$ goose up-by-one
$ OK 20170614145246_change_type.sql
回滚迁移
# 回滚单个迁移
$ goose down
$ OK 003_and_again.go
# 回滚到特定版本
$ goose down-to 20170506082527
$ OK 20170506082527_alter_column.sql
# 回滚所有迁移(谨慎使用)
$ goose down-to 0
查看状态
$ goose status
$ Applied At Migration
$ =======================================
$ Sun Jan 6 11:25:03 2013 -- 001_basics.sql
$ Sun Jan 6 11:25:03 2013 -- 002_next.sql
$ Pending -- 003_and_again.go
查看当前版本
$ goose version
$ goose: version 002
环境变量配置
可以通过环境变量配置Goose:
export GOOSE_DRIVER=DRIVER
export GOOSE_DBSTRING=DBSTRING
export GOOSE_MIGRATION_DIR=MIGRATION_DIR
export GOOSE_TABLE=TABLENAME
或者使用.env文件:
GOOSE_DRIVER=postgres
GOOSE_DBSTRING=postgres://admin:admin@localhost:5432/admin_db
GOOSE_MIGRATION_DIR=./migrations
GOOSE_TABLE=custom.goose_migrations
迁移文件类型
SQL迁移
SQL迁移文件示例:
-- +goose Up
CREATE TABLE post (
id int NOT NULL,
title text,
body text,
PRIMARY KEY(id)
);
-- +goose Down
DROP TABLE post;
Go迁移
Go迁移文件示例:
package migrations
import (
"database/sql"
"github.com/pressly/goose/v3"
)
func init() {
goose.AddMigration(Up, Down)
}
func Up(tx *sql.Tx) error {
_, err := tx.Exec("UPDATE users SET username='admin' WHERE username='root';")
if err != nil {
return err
}
return nil
}
func Down(tx *sql.Tx) error {
_, err := tx.Exec("UPDATE users SET username='root' WHERE username='admin';")
if err != nil {
return err
}
return nil
}
嵌入式SQL迁移
使用Go 1.16+的embed功能:
package main
import (
"database/sql"
"embed"
"github.com/pressly/goose/v3"
)
//go:embed migrations/*.sql
var embedMigrations embed.FS
func main() {
var db *sql.DB
// 设置数据库连接
goose.SetBaseFS(embedMigrations)
if err := goose.SetDialect("postgres"); err != nil {
panic(err)
}
if err := goose.Up(db, "migrations"); err != nil {
panic(err)
}
// 运行应用
}
完整示例
1. 初始化项目
mkdir myproject
cd myproject
go mod init myproject
go get github.com/pressly/goose/v3
2. 创建迁移目录和文件
mkdir -p migrations
goose create init sql
编辑生成的迁移文件(migrations/xxxx_init.sql):
-- +goose Up
CREATE TABLE users (
id SERIAL PRIMARY KEY,
username VARCHAR(255) NOT NULL UNIQUE,
email VARCHAR(255),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- +goose Down
DROP TABLE users;
3. 创建main.go
package main
import (
"database/sql"
"log"
_ "github.com/lib/pq"
"github.com/pressly/goose/v3"
)
func main() {
// 设置数据库连接
db, err := sql.Open("postgres", "user=postgres dbname=postgres sslmode=disable")
if err != nil {
log.Fatal(err)
}
defer db.Close()
// 运行迁移
if err := goose.SetDialect("postgres"); err != nil {
log.Fatal(err)
}
if err := goose.Up(db, "migrations"); err != nil {
log.Fatal(err)
}
log.Println("Migrations applied successfully!")
}
4. 运行迁移
go run main.go
注意事项
- 对于MySQL,需要在连接字符串中添加
parseTime=true
和multiStatements=true
参数 - 迁移文件必须以数字开头,后跟下划线
- Go迁移文件不能以
*_test.go
结尾 - 建议采用混合版本控制策略,开发时使用时间戳,生产环境使用顺序编号
Goose支持多种数据库,包括Postgres、MySQL、SQLite、MSSQL等,是一个功能强大且灵活的数据库迁移工具。
更多关于golang数据库迁移管理工具插件goose的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复
更多关于golang数据库迁移管理工具插件goose的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
Goose - Golang数据库迁移管理工具使用指南
Goose是一个简单而强大的数据库迁移工具,支持Go语言编写迁移脚本。它类似于Ruby的ActiveRecord迁移或Python的Alembic,但专为Go设计。
安装Goose
go get -u github.com/pressly/goose/v3/cmd/goose
基本使用
1. 初始化迁移目录
goose -dir=migrations create init_schema sql
这会在migrations
目录下创建两个文件:
XXXXXX_init_schema_up.sql
- 升级迁移XXXXXX_init_schema_down.sql
- 回滚迁移
2. 编写迁移文件
up.sql - 升级操作
-- +goose Up
CREATE TABLE users (
id SERIAL PRIMARY KEY,
username TEXT UNIQUE NOT NULL,
email TEXT UNIQUE NOT NULL,
created_at TIMESTAMP DEFAULT NOW()
);
-- +goose StatementBegin
CREATE OR REPLACE FUNCTION update_timestamp()
RETURNS TRIGGER AS $$
BEGIN
NEW.updated_at = NOW();
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
-- +goose StatementEnd
down.sql - 回滚操作
-- +goose Down
DROP TABLE IF EXISTS users;
DROP FUNCTION IF EXISTS update_timestamp;
3. 运行迁移
goose -dir=migrations postgres "user=postgres dbname=mydb sslmode=disable" up
Go代码集成
你也可以在Go代码中直接使用Goose:
package main
import (
"database/sql"
"log"
_ "github.com/lib/pq"
"github.com/pressly/goose/v3"
)
func main() {
db, err := sql.Open("postgres", "user=postgres dbname=mydb sslmode=disable")
if err != nil {
log.Fatal(err)
}
defer db.Close()
// 设置迁移目录
goose.SetBaseFS(nil) // 如果需要嵌入迁移文件,可以设置embed.FS
migrationDir := "migrations"
// 运行迁移
if err := goose.Up(db, migrationDir); err != nil {
log.Fatal(err)
}
// 或者运行特定版本
// if err := goose.UpTo(db, migrationDir, 20230801000000); err != nil {
// log.Fatal(err)
// }
}
高级功能
1. 使用Go迁移脚本
除了SQL,Goose还支持Go编写的迁移脚本:
goose -dir=migrations create add_user_columns go
这会生成一个Go模板文件:
package migrations
import (
"database/sql"
"github.com/pressly/goose/v3"
)
func init() {
goose.AddMigration(upAddUserColumns, downAddUserColumns)
}
func upAddUserColumns(tx *sql.Tx) error {
// 升级逻辑
_, err := tx.Exec("ALTER TABLE users ADD COLUMN age INT")
return err
}
func downAddUserColumns(tx *sql.Tx) error {
// 回滚逻辑
_, err := tx.Exec("ALTER TABLE users DROP COLUMN age")
return err
}
2. 状态检查
goose -dir=migrations postgres "user=postgres dbname=mydb sslmode=disable" status
3. 回滚迁移
# 回滚一步
goose -dir=migrations postgres "user=postgres dbname=mydb sslmode=disable" down
# 回滚到特定版本
goose -dir=migrations postgres "user=postgres dbname=mydb sslmode=disable" down-to 20230801000000
最佳实践
- 版本控制:确保迁移文件在版本控制系统中
- 原子性:每个迁移应该是原子的,要么完全成功,要么完全失败
- 测试:在生产环境运行前,先在测试环境测试迁移
- 顺序:迁移应该按照时间顺序执行,不要修改已提交的迁移文件
- 回滚:确保每个up迁移都有对应的down迁移
Goose是一个简单但功能强大的工具,可以帮助你管理数据库模式的变化,特别是在团队协作和持续集成/部署环境中非常有用。