// 一次性运维工具:直接加载项目配置执行 EnsureDB + EnsureSchema(建新表 + 幂等补列), // 绕过交互式管理员密码门禁(密码留在配置文件内,不落日志、不打印)。 // 用法:go run ./tools/migrateonce package main import ( "context" "fmt" "os" "bj_power_mes/internal/config" "bj_power_mes/internal/db" "github.com/zeromicro/go-zero/core/conf" ) func main() { var c config.Config conf.MustLoad("etc/bj_power_mes-api.yaml", &c) if err := db.EnsureDB(c.Database); err != nil { fmt.Println("ENSURE_DB_FAIL:", err) os.Exit(1) } client, sqlDB := db.MustNewDB(c.Database) defer client.Close() defer sqlDB.Close() // 迁移前现状:库名 + 现有表清单 rows, err := sqlDB.QueryContext(context.Background(), `SELECT current_database(), COALESCE(string_agg(tablename, ','), '(empty)') FROM pg_tables WHERE schemaname='public'`) if err == nil && rows.Next() { var dbname, tables string _ = rows.Scan(&dbname, &tables) rows.Close() fmt.Printf("DB=%s TABLES_BEFORE=%s\n", dbname, tables) } if err := db.EnsureSchema(client, sqlDB); err != nil { fmt.Println("MIGRATE_FAIL:", err) os.Exit(1) } // 迁移结果自检:新表存在 + 旧表新列存在 var tableExists bool if err := sqlDB.QueryRowContext(context.Background(), `SELECT EXISTS(SELECT 1 FROM information_schema.tables WHERE table_schema='public' AND table_name='workpiece_bind')`, ).Scan(&tableExists); err != nil { fmt.Println("VERIFY_FAIL:", err) os.Exit(1) } var colExists bool if err := sqlDB.QueryRowContext(context.Background(), `SELECT EXISTS(SELECT 1 FROM information_schema.columns WHERE table_schema='public' AND table_name='work_order_bom' AND column_name='process_code')`, ).Scan(&colExists); err != nil { fmt.Println("VERIFY_FAIL:", err) os.Exit(1) } var bindCols int _ = sqlDB.QueryRowContext(context.Background(), `SELECT COUNT(*) FROM information_schema.columns WHERE table_schema='public' AND table_name='workpiece_bind'`, ).Scan(&bindCols) fmt.Printf("MIGRATE_OK workpiece_bind_table=%v bom_item.process_code=%v workpiece_bind_cols=%d\n", tableExists, colExists, bindCols) if !tableExists || !colExists { os.Exit(1) } }