调整工具类的方法,优化方法调用及增加迁移工具及其用法

This commit is contained in:
2025-12-04 22:30:48 +08:00
parent de8fc13f18
commit 0650feb0d2
28 changed files with 3753 additions and 162 deletions

583
MIGRATION.md Normal file
View File

@@ -0,0 +1,583 @@
# 数据库迁移工具 - 完整指南
## 📌 核心特点
-**独立工具,零耦合** - 与应用代码完全分离
-**生产就绪** - 编译成二进制无需Go环境
-**灵活配置** - 支持命令行参数、环境变量、配置文件
-**Docker友好** - 挂载配置,修改无需重启容器
---
## 🚀 快速开始3步
> **黑盒模式**:迁移工具内部调用 `migration.RunMigrationsFromConfig()` 方法自动处理配置加载、数据库连接、迁移执行等所有细节。你只需要提供配置文件和SQL文件即可。
### 1. 复制迁移工具模板
```bash
mkdir -p cmd/migrate
cp /path/to/go-common/templates/migrate/main.go cmd/migrate/
```
### 2. 创建迁移文件
```bash
mkdir -p migrations
```
创建 `migrations/20240101000001_create_users.sql`
```sql
CREATE TABLE users (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(255) NOT NULL,
email VARCHAR(255) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
```
### 3. 编译和使用
```bash
# 编译(生产环境推荐)
go build -o bin/migrate cmd/migrate/main.go
# 使用
./bin/migrate up # 使用默认配置
./bin/migrate up -config /path/to/config.json # 指定配置
./bin/migrate status # 查看状态
./bin/migrate -help # 查看帮助
```
---
## 💻 本地使用
### 开发环境
```bash
# 直接运行需要Go环境
go run cmd/migrate/main.go up
go run cmd/migrate/main.go up -config dev.json
# 编译后运行(推荐)
go build -o bin/migrate cmd/migrate/main.go
./bin/migrate up
./bin/migrate up -config config.prod.json
./bin/migrate up -c prod.json -d db/migrations
```
### 命令说明
```bash
./bin/migrate -help
# 输出:
# 用法: migrate [命令] [选项]
#
# 命令:
# up 执行所有待执行的迁移(默认)
# down 回滚最后一个迁移
# status 查看迁移状态
#
# 选项:
# -config, -c 配置文件路径(默认: config.json
# -dir, -d 迁移文件目录(默认: migrations
# -help, -h 显示帮助信息
```
### 配置方式
#### 方式1配置文件推荐开发环境
`config.json`:
```json
{
"database": {
"type": "mysql",
"host": "localhost",
"port": 3306,
"user": "root",
"password": "password",
"database": "mydb"
}
}
```
#### 方式2环境变量推荐生产环境
```bash
# 使用 DATABASE_URL最简单
export DATABASE_URL="mysql://root:password@localhost:3306/mydb"
./bin/migrate up
# 覆盖配置路径
export CONFIG_FILE="/etc/app/config.json"
export MIGRATIONS_DIR="/opt/app/migrations"
./bin/migrate up
```
#### 配置优先级(从高到低)
1. 命令行参数 `-config``-dir`(最高)
2. 环境变量 `CONFIG_FILE``MIGRATIONS_DIR`
3. 环境变量 `DATABASE_URL`
4. 默认值 `config.json``migrations`
---
## 🐳 Docker 使用
### 方式1挂载配置文件推荐
**优势**:修改配置无需重启容器!
#### docker-compose.yml
```yaml
version: '3.8'
services:
app:
build: .
ports:
- "8080:8080"
volumes:
# 挂载配置文件(推荐:修改配置无需重启容器)
- ./config.json:/app/config.json:ro
# 启动时先执行迁移,再启动应用
command: sh -c "./migrate up && ./server"
```
#### 使用方式
```bash
# 1. 启动服务
docker-compose up -d
# 2. 修改配置文件
vim config.json
# 3. 手动执行迁移(无需重启容器!)
docker-compose exec app ./migrate up
# 4. 查看状态
docker-compose exec app ./migrate status
```
### 方式2指定配置文件路径
适用于多环境部署:
```yaml
services:
app:
build: .
volumes:
# 挂载不同环境的配置文件
- ./config.prod.json:/app/config.json:ro
command: sh -c "./migrate up -config /app/config.json && ./server"
```
```bash
# 手动切换环境(修改挂载的配置文件后)
docker-compose exec app ./migrate up
```
### 方式3使用环境变量
无需配置文件(适用于简单场景):
```yaml
services:
app:
build: .
environment:
DATABASE_URL: mysql://root:password@db:3306/mydb
command: sh -c "./migrate up && ./server"
# 注意DATABASE_URL 的值应该指向你的数据库服务
# 例如mysql://user:pass@your-db-host:3306/dbname
```
### Dockerfile
```dockerfile
FROM golang:1.21 as builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
# 编译应用和迁移工具
RUN go build -o bin/server cmd/server/main.go
RUN go build -o bin/migrate cmd/migrate/main.go
FROM debian:bookworm-slim
WORKDIR /app
RUN apt-get update && apt-get install -y ca-certificates && rm -rf /var/lib/apt/lists/*
# 复制二进制文件和迁移文件
COPY --from=builder /app/bin/migrate .
COPY --from=builder /app/bin/server .
COPY --from=builder /app/migrations ./migrations
EXPOSE 8080
# 启动:先迁移,再启动应用
CMD ["sh", "-c", "./migrate up && ./server"]
# 注意:配置文件通过 volumes 挂载,不打包进镜像
```
---
## ☸️ Kubernetes 部署
### 使用 Job 执行迁移
```yaml
# k8s-job-migrate.yaml
apiVersion: batch/v1
kind: Job
metadata:
name: db-migrate
spec:
template:
spec:
containers:
- name: migrate
image: myapp:latest
command: ["./migrate", "up", "-config", "/etc/config/database.json"]
volumeMounts:
- name: config
mountPath: /etc/config
readOnly: true
volumes:
- name: config
configMap:
name: app-config
restartPolicy: OnFailure
```
### 部署流程
```bash
# 1. 创建 ConfigMap
kubectl create configmap app-config --from-file=config.json
# 2. 执行迁移
kubectl apply -f k8s-job-migrate.yaml
kubectl wait --for=condition=complete job/db-migrate
# 3. 部署应用
kubectl apply -f k8s-deployment.yaml
```
---
## 🔧 CI/CD 集成
### GitLab CI
```yaml
# .gitlab-ci.yml
stages:
- build
- migrate
- deploy
build:
stage: build
script:
- go build -o bin/migrate cmd/migrate/main.go
- go build -o bin/server cmd/server/main.go
artifacts:
paths:
- bin/
migrate:
stage: migrate
script:
- ./bin/migrate up -config config.prod.json
environment:
name: production
deploy:
stage: deploy
script:
- ./bin/server
```
### GitHub Actions
```yaml
# .github/workflows/deploy.yml
name: Deploy
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Go
uses: actions/setup-go@v4
with:
go-version: '1.21'
- name: Build
run: |
go build -o bin/migrate cmd/migrate/main.go
go build -o bin/server cmd/server/main.go
- name: Run Migrations
env:
DATABASE_URL: ${{ secrets.DATABASE_URL }}
run: ./bin/migrate up
- name: Deploy
run: ./bin/server
```
---
## 📁 迁移文件管理
### 文件命名规则
```
migrations/
├── 20240101000001_create_users.sql # Up 迁移
├── 20240101000001_create_users.down.sql # Down 回滚(可选)
├── 20240102000001_add_posts.sql
└── 20240102000001_add_posts.down.sql
```
格式:`{时间戳}_{描述}.sql`
### 创建迁移文件
```bash
# 获取时间戳
date +%Y%m%d%H%M%S
# 输出20240101120000
# 创建迁移文件
vim migrations/20240101120000_create_posts.sql
```
### 迁移文件示例
**Up 文件**
```sql
-- migrations/20240101000001_create_users.sql
CREATE TABLE users (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(255) NOT NULL UNIQUE,
email VARCHAR(255) NOT NULL UNIQUE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX idx_users_email ON users(email);
```
**Down 文件**(可选):
```sql
-- migrations/20240101000001_create_users.down.sql
DROP INDEX idx_users_email ON users;
DROP TABLE IF EXISTS users;
```
### 兼容性建议
使用条件语句确保迁移可重复执行:
```sql
-- 创建表
CREATE TABLE IF NOT EXISTS users (...);
-- 添加列
ALTER TABLE posts ADD COLUMN IF NOT EXISTS author_id BIGINT;
-- 创建索引
CREATE INDEX IF NOT EXISTS idx_posts_author ON posts(author_id);
```
---
## 🔍 常见问题
### Q: 为什么不直接在应用代码中调用?
**A**: **耦合度太高!** 独立工具的优势:
- ✅ 应用和迁移完全解耦
- ✅ 可以独立部署和执行
- ✅ 更灵活的部署策略
- ✅ 符合单一职责原则
### Q: 生产环境没有Go怎么办
**A**: **编译成二进制文件**
```bash
# 本地或CI中编译
go build -o bin/migrate cmd/migrate/main.go
# 部署二进制文件不需要Go环境
scp bin/migrate server:/app/
ssh server "/app/migrate up"
```
### Q: Docker中修改配置需要重启吗
**A**: **不需要!** 使用挂载方式:
```yaml
volumes:
- ./config.json:/app/config.json:ro
```
修改后直接执行:
```bash
docker-compose exec app ./migrate up
```
### Q: 如何指定不同的配置文件?
**A**: 使用命令行参数:
```bash
# 开发环境
./migrate up -config config.dev.json
# 测试环境
./migrate up -config config.test.json
# 生产环境
./migrate up -config /etc/app/config.prod.json
```
### Q: 多个实例同时启动会有问题吗?
**A**: 不会。数据库会保证只有一个实例能执行迁移(通过版本号主键)。
### Q: Docker连不上数据库
**A**: 注意主机名:
-`localhost`(容器内无法访问宿主机)
-`db`docker-compose 服务名)
-`host.docker.internal`Mac/Windows 访问宿主机)
---
## 💡 最佳实践
### 1. 开发环境
- 使用 `go run` 快速迭代
- 使用配置文件管理不同环境
```bash
go run cmd/migrate/main.go up -config config.dev.json
```
### 2. 测试环境
- 编译后部署,模拟生产环境
- 使用独立的数据库
```bash
go build -o bin/migrate cmd/migrate/main.go
./bin/migrate up -config config.test.json
```
### 3. 生产环境
- 编译后部署,先执行迁移再启动应用
- 使用环境变量管理敏感信息
```bash
go build -o bin/migrate cmd/migrate/main.go
DATABASE_URL="mysql://..." ./bin/migrate up
./bin/server
```
### 4. Docker 部署
- 多阶段构建,只包含二进制文件
- 挂载配置文件,灵活修改
```dockerfile
FROM golang:1.21 as builder
RUN go build -o bin/migrate cmd/migrate/main.go
FROM debian:bookworm-slim
COPY --from=builder /app/bin/migrate .
CMD ["sh", "-c", "./migrate up && ./server"]
```
### 5. CI/CD
- 在构建阶段编译
- 部署前执行迁移
```yaml
- build: go build -o bin/migrate cmd/migrate/main.go
- migrate: ./bin/migrate up
- deploy: ./bin/server
```
---
## 📊 推荐的项目结构
```
your-project/
├── cmd/
│ ├── migrate/
│ │ └── main.go # 迁移工具(独立)
│ └── server/
│ └── main.go # 应用主程序
├── migrations/ # 迁移SQL文件
│ ├── 20240101000001_create_users.sql
│ └── 20240101000001_create_users.down.sql
├── config.json # 配置文件
├── Dockerfile
├── docker-compose.yml
├── Makefile # 常用命令
└── go.mod
```
---
## 📚 更多资源
- [模板文件](./templates/) - 可直接复制的模板
- [完整文档](./docs/migration.md) - 详细功能文档
- [配置文档](./docs/config.md) - 配置说明
---
## 🎯 总结
使用 GoCommon 的迁移工具,你可以:
1. ✅ 复制一个模板文件到 `cmd/migrate/main.go`
2. ✅ 创建 SQL 迁移文件到 `migrations/`
3. ✅ 编译:`go build -o bin/migrate cmd/migrate/main.go`
4. ✅ 使用:`./bin/migrate up`
**核心优势**
- 独立工具,零耦合
- 生产就绪无需Go环境
- 灵活配置,支持多环境
- Docker友好修改配置无需重启
**开箱即用,灵活强大!** 🎉