Files
go-common/docs/migration.md

243 lines
5.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 数据库迁移工具文档
## 概述
数据库迁移工具提供了数据库版本管理和迁移功能支持MySQL、PostgreSQL、SQLite等数据库。使用GORM作为数据库操作库可以方便地进行数据库结构的版本控制。
## 功能特性
- 支持迁移版本管理
- 支持迁移和回滚操作
- 支持从文件系统加载迁移文件
- 支持迁移状态查询
- 自动创建迁移记录表
- 事务支持,确保迁移的原子性
## 使用方法
### 1. 创建迁移器
```go
import (
"gorm.io/driver/mysql"
"gorm.io/gorm"
"github.com/go-common/migration"
)
// 初始化数据库连接
dsn := "user:password@tcp(localhost:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local"
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
// 创建迁移器
migrator := migration.NewMigrator(db)
// 或者指定自定义的迁移记录表名
migrator := migration.NewMigrator(db, "my_migrations")
```
### 2. 添加迁移
#### 方式一:代码方式添加迁移
```go
migrator.AddMigration(migration.Migration{
Version: "20240101000001",
Description: "create_users_table",
Up: func(db *gorm.DB) error {
return db.Exec(`
CREATE TABLE users (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(255) NOT NULL,
email VARCHAR(255) UNIQUE NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)
`).Error
},
Down: func(db *gorm.DB) error {
return db.Exec("DROP TABLE IF EXISTS users").Error
},
})
```
#### 方式二:批量添加迁移
```go
migrations := []migration.Migration{
{
Version: "20240101000001",
Description: "create_users_table",
Up: func(db *gorm.DB) error {
return db.Exec("CREATE TABLE users ...").Error
},
Down: func(db *gorm.DB) error {
return db.Exec("DROP TABLE users").Error
},
},
{
Version: "20240101000002",
Description: "add_index_to_users",
Up: func(db *gorm.DB) error {
return db.Exec("CREATE INDEX idx_email ON users(email)").Error
},
Down: func(db *gorm.DB) error {
return db.Exec("DROP INDEX idx_email ON users").Error
},
},
}
migrator.AddMigrations(migrations...)
```
#### 方式三:从文件加载迁移
```go
// 文件命名格式: {version}_{description}.sql 或 {version}_{description}.up.sql
// 例如: 20240101000001_create_users_table.up.sql
// 对应的回滚文件: 20240101000001_create_users_table.down.sql
migrations, err := migration.LoadMigrationsFromFiles("./migrations", "*.up.sql")
if err != nil {
log.Fatal(err)
}
migrator.AddMigrations(migrations...)
```
### 3. 执行迁移
```go
// 执行所有未应用的迁移
err := migrator.Up()
if err != nil {
log.Fatal(err)
}
```
### 4. 回滚迁移
```go
// 回滚最后一个迁移
err := migrator.Down()
if err != nil {
log.Fatal(err)
}
```
### 5. 查看迁移状态
```go
status, err := migrator.Status()
if err != nil {
log.Fatal(err)
}
for _, s := range status {
fmt.Printf("Version: %s, Description: %s, Applied: %v\n",
s.Version, s.Description, s.Applied)
}
```
### 6. 生成迁移版本号
```go
// 生成基于时间戳的版本号
version := migration.GenerateVersion()
// 输出: 1704067200 (Unix时间戳)
```
## API 参考
### Migration 结构体
```go
type Migration struct {
Version string // 迁移版本号(必须唯一)
Description string // 迁移描述
Up func(*gorm.DB) error // 升级函数
Down func(*gorm.DB) error // 回滚函数(可选)
}
```
### Migrator 方法
#### NewMigrator(db *gorm.DB, tableName ...string) *Migrator
创建新的迁移器。
**参数:**
- `db`: GORM数据库连接
- `tableName`: 可选,迁移记录表名,默认为 "schema_migrations"
**返回:** 迁移器实例
#### AddMigration(migration Migration)
添加单个迁移。
#### AddMigrations(migrations ...Migration)
批量添加迁移。
#### Up() error
执行所有未应用的迁移。按版本号升序执行。
**返回:** 错误信息
#### Down() error
回滚最后一个已应用的迁移。
**返回:** 错误信息
#### Status() ([]MigrationStatus, error)
查看所有迁移的状态。
**返回:** 迁移状态列表和错误信息
### MigrationStatus 结构体
```go
type MigrationStatus struct {
Version string // 版本号
Description string // 描述
Applied bool // 是否已应用
}
```
### 辅助函数
#### LoadMigrationsFromFiles(dir string, pattern string) ([]Migration, error)
从文件系统加载迁移文件。
**参数:**
- `dir`: 迁移文件目录
- `pattern`: 文件匹配模式,如 "*.up.sql"
**返回:** 迁移列表和错误信息
**文件命名格式:** `{version}_{description}.up.sql`
**示例:**
- `20240101000001_create_users_table.up.sql` - 升级文件
- `20240101000001_create_users_table.down.sql` - 回滚文件(可选)
#### GenerateVersion() string
生成基于时间戳的迁移版本号。
**返回:** Unix时间戳字符串
## 注意事项
1. 迁移版本号必须唯一,建议使用时间戳格式
2. 迁移操作在事务中执行,失败会自动回滚
3. 迁移记录表会自动创建,无需手动创建
4. 如果迁移文件没有对应的down文件回滚操作会失败
5. 迁移按版本号升序执行,确保顺序正确
## 示例
完整示例请参考 `examples/migration_example.go`