/** * 导入 life JSON 数据到数据库 * 运行: bun run scripts/import-life.ts */ import { drizzle } from 'drizzle-orm/node-postgres'; import { life } from '@/db/schemas/life-schema.ts'; import { useConfig } from '@kevisual/use-config'; import { readFileSync } from 'node:fs'; import { resolve } from 'node:path'; const config = useConfig() as any; const DATABASE_URL = config.DATABASE_URL || process.env.DATABASE_URL || ''; if (!DATABASE_URL) { console.error('缺少 DATABASE_URL 配置'); process.exit(1); } const db = drizzle(DATABASE_URL); // 读取 JSON 数据 const jsonPath = resolve(import.meta.dir, 'life-list.json'); const rawData = JSON.parse(readFileSync(jsonPath, 'utf-8')) as Array<{ data: Record; description: string; effectiveAt: string; link: string; prompt: string; summary: string; tags: string[]; taskResult: Record; taskType: string; title: string; type: string; updatedAt: string; userId: string; }>; async function importData() { console.log(`准备导入 ${rawData.length} 条 flowme-life 数据...`); let inserted = 0; let skipped = 0; for (const item of rawData) { const uid = item.userId; try { await db .insert(life) .values({ title: item.title || '', summary: item.summary || '', description: item.description || '', tags: item.tags ?? [], link: item.link || '', data: item.data ?? {}, effectiveAt: item.effectiveAt || '', type: item.type || '', prompt: item.prompt || '', taskType: item.taskType || '', taskResult: item.taskResult ?? {}, uid: uid as any, }) .onConflictDoNothing(); console.log(` ✓ 导入: title=${item.title}, type=${item.type}`); inserted++; } catch (err: any) { const cause = err.cause || err; console.warn(` ✗ 跳过: title=${item.title} — ${cause.message || err.message}`); skipped++; } } console.log(`\n完成: 成功 ${inserted} 条,跳过 ${skipped} 条`); process.exit(0); } importData().catch((err) => { console.error('导入失败:', err); process.exit(1); });