import { PrismaClient } from "@prisma/client"; import { PrismaMariaDb } from "@prisma/adapter-mariadb"; import "dotenv/config"; const base = process.env.DATABASE_URL.replace("mysql://", "mariadb://"); const sep = base.includes("?") ? "&" : "?"; const connectionString = `${base}${sep}connection_limit=5&pool_timeout=10`; const adapter = new PrismaMariaDb(connectionString); const prisma = new PrismaClient({ adapter }); async function main() { console.log("=== 修复 PendingTool categoryId 为 NULL 的记录 ===\n"); const categories = await prisma.category.findMany({ select: { id: true, name: true }, orderBy: { id: "asc" } }); if (categories.length === 0) { console.error("错误: 数据库中没有分类数据"); await prisma.$disconnect(); return; } const defaultCategoryId = categories[0].id; console.log(`默认分类: id=${defaultCategoryId} "${categories[0].name}"`); const nullCatTools = await prisma.pendingTool.findMany({ where: { categoryId: null, status: "pending" }, select: { id: true, name: true, websiteUrl: true }, }); const catIds = new Set(categories.map(c => c.id)); const invalidCatTools = await prisma.pendingTool.findMany({ where: { status: "pending", categoryId: { not: null } }, select: { id: true, name: true, categoryId: true }, }); const invalidCat = invalidCatTools.filter(t => !catIds.has(t.categoryId)); console.log(`\nPendingTool 统计:`); console.log(` categoryId 为 NULL: ${nullCatTools.length} 条`); console.log(` categoryId 指向无效分类: ${invalidCat.length} 条`); let totalFixed = 0; if (nullCatTools.length > 0) { console.log(`\n修复 categoryId 为 NULL 的记录:`); for (const t of nullCatTools) { console.log(` id=${t.id} "${t.name}" → categoryId: ${defaultCategoryId}`); await prisma.pendingTool.update({ where: { id: t.id }, data: { categoryId: defaultCategoryId } }); totalFixed++; } } if (invalidCat.length > 0) { console.log(`\n修复 categoryId 指向无效分类的记录:`); for (const t of invalidCat) { console.log(` id=${t.id} "${t.name}" (categoryId=${t.categoryId}) → ${defaultCategoryId}`); await prisma.pendingTool.update({ where: { id: t.id }, data: { categoryId: defaultCategoryId } }); totalFixed++; } } if (totalFixed === 0) { console.log("\n无需修复,所有 PendingTool 记录的 categoryId 均有效。"); } else { console.log(`\n✅ 共修复 ${totalFixed} 条记录`); } console.log("\n建议后续操作:"); console.log(" 1. 重新部署 task3-check-tools.mjs 到服务器 scripts/ 目录"); console.log(" 2. 重启 CRON 容器: docker compose restart cron"); console.log(" 3. 验证: 等待下次 task3 执行确认无 FK 错误"); } main() .catch((e) => { console.error(e); process.exit(1); }) .finally(async () => { await prisma.$disconnect(); });