golang数据库迁移工具插件库migrate的使用

Golang数据库迁移工具插件库migrate的使用

migrate是一个用Go编写的数据库迁移工具,可以作为CLI使用或作为库导入到你的Go项目中。

功能特点

  • 从源读取迁移文件并按正确顺序应用到数据库
  • 驱动程序设计简单,migrate负责所有逻辑处理
  • 数据库驱动程序不会假设或尝试纠正用户输入,有疑问时会直接报错

支持的数据库

migrate支持多种数据库,包括:

  • PostgreSQL
  • MySQL/MariaDB
  • SQLite
  • MongoDB
  • Cassandra/ScyllaDB
  • Google Cloud Spanner
  • CockroachDB
  • MS SQL Server
  • 以及其他多种数据库

基本使用示例

CLI基本用法

$ migrate -source file://path/to/migrations -database postgres://localhost:5432/database up 2

Docker使用

$ docker run -v {{ migration dir }}:/migrations --network host migrate/migrate \
    -path=/migrations/ -database postgres://localhost:5432/database up 2

在Go项目中使用

基本示例

import (
    "github.com/golang-migrate/migrate/v4"
    _ "github.com/golang-migrate/migrate/v4/database/postgres"
    _ "github.com/golang-migrate/migrate/v4/source/github"
)

func main() {
    m, err := migrate.New(
        "github://mattes:personal-access-token@mattes/migrate_test",
        "postgres://localhost:5432/database?sslmode=enable")
    m.Steps(2)
}

使用现有数据库连接

import (
    "database/sql"
    _ "github.com/lib/pq"
    "github.com/golang-migrate/migrate/v4"
    "github.com/golang-migrate/migrate/v4/database/postgres"
    _ "github.com/golang-migrate/migrate/v4/source/file"
)

func main() {
    db, err := sql.Open("postgres", "postgres://localhost:5432/database?sslmode=enable")
    driver, err := postgres.WithInstance(db, &postgres.Config{})
    m, err := migrate.NewWithDatabaseInstance(
        "file:///migrations",
        "postgres", driver)
    m.Up() // 或者使用m.Steps(2)明确设置要运行的迁移数量
}

迁移文件

每个迁移都有一个up和down迁移文件:

1481574547_create_users_table.up.sql
1481574547_create_users_table.down.sql

版本支持

版本 是否支持 导入路径 说明
master import "github.com/golang-migrate/migrate/v4" 新功能和错误修复首先出现在这里
v4 import "github.com/golang-migrate/migrate/v4" 用于稳定版本
v3 import "github.com/golang-migrate/migrate"import "gopkg.in/golang-migrate/migrate.v3" 不再支持

开发与贡献

欢迎贡献!请阅读开发指南和FAQ。


更多关于golang数据库迁移工具插件库migrate的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang数据库迁移工具插件库migrate的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


Golang数据库迁移工具migrate使用指南

migrate是一个流行的Golang数据库迁移工具,支持多种数据库系统,包括PostgreSQL、MySQL、SQLite、MongoDB等。下面我将详细介绍如何使用migrate进行数据库迁移。

安装migrate

首先安装migrate命令行工具和Go库:

# 安装命令行工具
go install -tags 'postgres' github.com/golang-migrate/migrate/v4/cmd/migrate@latest

# 添加依赖到项目
go get -u github.com/golang-migrate/migrate/v4

基本使用

1. 创建迁移文件

migrate create -ext sql -dir db/migrations -seq create_users_table

这会创建两个文件:

  • db/migrations/000001_create_users_table.up.sql - 升级迁移
  • db/migrations/000001_create_users_table.down.sql - 回滚迁移

2. 编写迁移SQL

在up文件中添加创建表的SQL:

-- db/migrations/000001_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
);

在down文件中添加删除表的SQL:

-- db/migrations/000001_create_users_table.down.sql
DROP TABLE IF EXISTS users;

3. 执行迁移

在Go代码中执行迁移:

package main

import (
	"log"

	"github.com/golang-migrate/migrate/v4"
	_ "github.com/golang-migrate/migrate/v4/database/postgres"
	_ "github.com/golang-migrate/migrate/v4/source/file"
)

func main() {
	m, err := migrate.New(
		"file://db/migrations",
		"postgres://user:password@localhost:5432/dbname?sslmode=disable")
	if err != nil {
		log.Fatal(err)
	}
	defer m.Close()

	// 执行所有待处理的迁移
	if err := m.Up(); err != nil && err != migrate.ErrNoChange {
		log.Fatal(err)
	}
}

高级功能

1. 版本控制

// 获取当前版本
version, dirty, err := m.Version()
if err != nil {
    log.Fatal(err)
}
fmt.Printf("Current version: %d, dirty: %v\n", version, dirty)

// 迁移到特定版本
err = m.Migrate(2) // 迁移到版本2
if err != nil {
    log.Fatal(err)
}

// 回滚一步
err = m.Steps(-1)
if err != nil {
    log.Fatal(err)
}

2. 使用嵌入文件系统

将迁移文件嵌入到二进制文件中:

import (
	"embed"
	"github.com/golang-migrate/migrate/v4/source/iofs"
)

//go:embed db/migrations/*.sql
var fs embed.FS

func main() {
	d, err := iofs.New(fs, "db/migrations")
	if err != nil {
		log.Fatal(err)
	}

	m, err := migrate.NewWithSourceInstance("iofs", d, "postgres://...")
	if err != nil {
		log.Fatal(err)
	}
	// ...
}

3. 自定义迁移源

type MySource struct {
    // 实现migrate.Source接口
}

m, err := migrate.NewWithSourceInstance("custom", &MySource{}, "postgres://...")

最佳实践

  1. 原子性迁移:每个迁移应该是一个原子操作,要么完全成功,要么完全失败。

  2. 幂等性:迁移脚本应该是幂等的,可以安全地多次执行。

  3. 小步迁移:每个迁移应该只做一件事,保持迁移小而简单。

  4. 测试迁移:在测试环境中测试迁移和回滚。

  5. 版本控制:将迁移文件与应用程序代码一起进行版本控制。

常见问题解决

  1. 数据库锁定:migrate使用锁表来防止并发迁移,如果迁移意外中断可能导致锁表。可以手动删除锁表或使用force命令。

  2. 脏状态:如果迁移部分失败,数据库会标记为"dirty"。需要手动修复并运行m.Force(version)清除脏状态。

  3. 环境变量:建议使用环境变量管理数据库连接字符串:

dsn := fmt.Sprintf("postgres://%s:%s@%s:%s/%s?sslmode=disable",
    os.Getenv("DB_USER"),
    os.Getenv("DB_PASSWORD"),
    os.Getenv("DB_HOST"),
    os.Getenv("DB_PORT"),
    os.Getenv("DB_NAME"))

migrate是一个强大而灵活的数据库迁移工具,通过合理使用可以大大简化数据库版本管理的工作。

回到顶部