// 把 prisma/migrations/manual/*.sql 直接 apply 到当前 DATABASE_URL // 不依赖 prisma migrate dev(项目无 migrations 历史 + 无 shadow DB) // // 用法: node scripts/apply-migration.mjs import { PrismaClient } from "@prisma/client"; import { readFile } from "node:fs/promises"; const prisma = new PrismaClient({ log: ["warn", "error"] }); async function main() { const file = process.argv[2]; if (!file) { console.error("用法: node scripts/apply-migration.mjs "); process.exit(2); } const sql = await readFile(file, "utf-8"); // 先按行去掉所有 -- 注释行,再按 ; 切分,过滤空段 const cleaned = sql .split("\n") .filter((l) => !/^\s*--/.test(l)) .join("\n"); const statements = cleaned .split(/;\s*(?:\n|$)/) .map((s) => s.trim()) .filter(Boolean); console.log(`将执行 ${statements.length} 条 SQL:\n`); statements.forEach((s, i) => console.log(` [${i + 1}] ${s.split("\n")[0]}...`)); console.log(""); for (const [i, stmt] of statements.entries()) { console.log(`[${i + 1}/${statements.length}] 执行中...`); try { await prisma.$executeRawUnsafe(stmt); console.log(`[${i + 1}] ✓ 成功`); } catch (e) { console.error(`[${i + 1}] ✗ 失败: ${e.message}`); throw e; } } console.log("\n=== 全部成功 ==="); await prisma.$disconnect(); } main().catch(async (e) => { console.error("\n[ABORT]", e.message); await prisma.$disconnect(); process.exit(1); });