Files
junhong_cmp_fiber/scripts/migrate.sh
2025-11-19 14:28:00 +08:00

150 lines
4.6 KiB
Bash
Executable File

#!/bin/bash
# 数据库迁移脚本
# 用法: ./scripts/migrate.sh [up|down|create|version|force] [args]
set -e
# 加载 .env 文件 (如果存在)
if [ -f .env ]; then
echo "正在加载 .env 文件..."
export $(grep -v '^#' .env | xargs)
fi
# 默认配置
MIGRATIONS_DIR="${MIGRATIONS_DIR:-migrations}"
DB_HOST="${DB_HOST:-localhost}"
DB_PORT="${DB_PORT:-5432}"
DB_USER="${DB_USER:-postgres}"
DB_PASSWORD="${DB_PASSWORD:-password}"
DB_NAME="${DB_NAME:-junhong_cmp}"
DB_SSLMODE="${DB_SSLMODE:-disable}"
# 构建数据库 URL
DATABASE_URL="postgresql://${DB_USER}:${DB_PASSWORD}@${DB_HOST}:${DB_PORT}/${DB_NAME}?sslmode=${DB_SSLMODE}"
# 检查 migrate 命令是否存在
if ! command -v migrate &> /dev/null; then
echo "错误: migrate 命令未找到"
echo "请安装 golang-migrate:"
echo " brew install golang-migrate (macOS)"
echo " 或访问 https://github.com/golang-migrate/migrate/tree/master/cmd/migrate#installation"
exit 1
fi
# 显示使用说明
show_usage() {
cat << EOF
用法: $0 [命令] [参数]
命令:
up [N] 向上迁移 N 步 (默认: 全部,完成后自动检查 legacy 表)
down [N] 向下回滚 N 步 (默认: 1)
create NAME 创建新的迁移文件
version 显示当前迁移版本
force V 强制设置迁移版本为 V (用于修复脏数据库状态)
check-legacy 检查 legacy 表 (tb_user/tb_order) 是否仍存在
help 显示此帮助信息
环境变量:
DB_HOST 数据库主机 (默认: localhost)
DB_PORT 数据库端口 (默认: 5432)
DB_USER 数据库用户 (默认: postgres)
DB_PASSWORD 数据库密码 (默认: password)
DB_NAME 数据库名称 (默认: junhong_cmp)
DB_SSLMODE SSL 模式 (默认: disable)
示例:
$0 up # 应用所有迁移
$0 down 1 # 回滚最后一次迁移
$0 create add_sim_table # 创建新迁移文件
$0 version # 查看当前版本
$0 force 1 # 强制设置版本为 1
$0 check-legacy # 单独检查 tb_user/tb_order 是否存在
EOF
}
check_legacy_tables() {
if ! command -v psql &> /dev/null; then
echo "提示: 未检测到 psql 命令,跳过 legacy 表检查"
return
fi
echo "正在检查 legacy 表 tb_user / tb_order..."
if ! CHECK_RESULT=$(psql "$DATABASE_URL" -Atqc "SELECT table_name FROM information_schema.tables WHERE table_schema='public' AND table_name IN ('tb_user','tb_order');"); then
echo "警告: 无法执行 legacy 表检查,请手动确认"
return
fi
if [ -z "$CHECK_RESULT" ]; then
echo "✓ 未发现 legacy 表,数据库结构已与代码同步"
else
echo "⚠ 检测到以下 legacy 表仍然存在:"
echo "$CHECK_RESULT" | while read -r table_name; do
if [ -n "$table_name" ]; then
printf ' - %s\n' "$table_name"
fi
done
echo "请确保已经执行 000004_drop_legacy_user_order 迁移或手动清理上述表"
fi
}
# 主命令处理
case "$1" in
up)
if [ -z "$2" ]; then
echo "正在应用所有迁移..."
migrate -path "$MIGRATIONS_DIR" -database "$DATABASE_URL" up
else
echo "正在向上迁移 $2 步..."
migrate -path "$MIGRATIONS_DIR" -database "$DATABASE_URL" up "$2"
fi
echo "迁移完成,开始检查 legacy 表..."
check_legacy_tables
;;
down)
STEPS="${2:-1}"
echo "正在向下回滚 $STEPS 步..."
migrate -path "$MIGRATIONS_DIR" -database "$DATABASE_URL" down "$STEPS"
;;
create)
if [ -z "$2" ]; then
echo "错误: 请提供迁移文件名称"
echo "用法: $0 create <name>"
exit 1
fi
echo "创建迁移文件: $2"
migrate create -ext sql -dir "$MIGRATIONS_DIR" -seq "$2"
echo "迁移文件创建成功:"
ls -lt "$MIGRATIONS_DIR" | head -3
;;
version)
echo "当前迁移版本:"
migrate -path "$MIGRATIONS_DIR" -database "$DATABASE_URL" version
;;
force)
if [ -z "$2" ]; then
echo "错误: 请提供版本号"
echo "用法: $0 force <version>"
exit 1
fi
echo "强制设置迁移版本为: $2"
migrate -path "$MIGRATIONS_DIR" -database "$DATABASE_URL" force "$2"
;;
check-legacy)
check_legacy_tables
;;
help|--help|-h)
show_usage
;;
*)
echo "错误: 未知命令 '$1'"
echo ""
show_usage
exit 1
;;
esac
echo "✓ 迁移操作完成"