{
  "id": "ai-generates-invalid-prisma-relations",
  "type": "failures",
  "category": "failures",
  "locale": "zh",
  "url": "/zh/failures/ai-generates-invalid-prisma-relations",
  "title": "如何修复AI生成的无效Prisma关系",
  "description": "AI代理生成的Prisma schema关系缺少反向关系、错误的引用操作或字段类型不匹配，导致prisma validate和prisma migrate失败。",
  "tools": [
    "Cursor",
    "Claude Code",
    "Codex",
    "Windsurf"
  ],
  "stack": [
    "PostgreSQL",
    "TypeScript"
  ],
  "tags": [
    "prisma",
    "postgres",
    "sql"
  ],
  "difficulty": null,
  "updated": "2026-06-08",
  "markdown": "AI代理编写的Prisma schema关系看起来正确，但由于缺少反向引用、类型不匹配或多关系设置不明确，导致`prisma validate`失败。\n\n## 症状\n\n一个关系在一个模型上声明，但在另一个模型上没有对应的必需部分，或者外键字段类型与引用的字段不匹配。\n\n```prisma\n// schema.prisma — WRONG\nmodel User {\n  id    String @id @default(cuid())\n  posts Post[]\n}\n\nmodel Post {\n  id       String @id @default(cuid())\n  authorId Int    // Int, but User.id is String — type mismatch\n  // Missing: author User @relation(fields: [authorId], references: [id])\n}\n```\n\n运行`prisma validate`会产生：\n\n```\nError: The relation field `posts` on model `User` is missing an opposite\nrelation field on the model `Post`.\n```\n\n## 发生原因\n\nAI代理经常只写关系的一边而忘记添加另一边，尤其是在多对多或自引用的情况下。它还会从记忆中复制字段类型，而不检查`authorId`是否必须与引用的`id`类型完全匹配。\n\n## 如何发现\n\n- `prisma validate`或`prisma migrate dev`失败并出现关系错误。\n- 一个模型有数组字段（一对多），但引用的模型没有标量外键或`@relation`属性。\n- 多对多使用了类型不匹配的显式连接表。\n- 自引用模型（例如类别树）只有`@relation(name: \"...\")`对的一边。\n\n## 如何修复\n\n每个关系必须声明两边。外键标量类型必须与引用的字段类型完全匹配。\n\n```prisma\n// schema.prisma — CORRECT\nmodel User {\n  id    String @id @default(cuid())\n  posts Post[] // one-to-many: back-reference\n}\n\nmodel Post {\n  id       String @id @default(cuid())\n  authorId String                       // String, matches User.id\n  author   User   @relation(fields: [authorId], references: [id], onDelete: Cascade)\n}\n```\n\n对于自引用树：\n\n```prisma\nmodel Category {\n  id       String     @id @default(cuid())\n  parentId String?\n  parent   Category?  @relation(\"CategoryTree\", fields: [parentId], references: [id])\n  children Category[] @relation(\"CategoryTree\")\n}\n```\n\n```txt\n[ ] Run \"prisma validate\" before \"prisma migrate dev\" — fix all errors first\n[ ] Every @relation on model A has a matching field on model B\n[ ] Foreign key scalar type matches the referenced @id type (String/Int/cuid)\n[ ] Self-referential relations use a named @relation(\"name\") on both sides\n[ ] Explicit many-to-many join tables declare both foreign keys with onDelete\n[ ] onDelete referential action is explicit (Cascade, Restrict, SetNull) — not left to default\n```\n\n## 修复提示\n\n```txt title=\"Fix Prompt\"\nThis Prisma schema fails prisma validate. Fix every relation error: add the\nmissing back-reference fields, ensure all foreign key scalar types exactly match\nthe referenced @id type, give every self-referential relation a unique name on\nboth sides, and set explicit onDelete actions (Cascade for required relations,\nSetNull for optional). Run prisma validate after each change until it passes.\n```\n\n## 测试\n\n```bash\n# Validate schema before attempting migration\nnpx prisma validate && echo \"Schema OK\" || echo \"FAIL: schema invalid\"\n\n# Also check for type mismatches (Int fk -> String id is a common error)\ngrep -A3 \"@relation\" prisma/schema.prisma\n```"
}