#!/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 " 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 " 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 "✓ 迁移操作完成"