GraphQL查询多对多关联返回空数组问题(Prisma-Pothos)
问题解决指南
1. 修复Prisma关联模型定义
你当前的多对多关联存在字段名不统一、关联名称缺失的问题,导致Prisma无法正确识别关联关系:
model User { id String @id @default(uuid()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt email String? @unique image String? role Role @default(USER) posts Post[] @relation("UserPosts") // 指定统一关联名称,字段名改为小写符合惯例 } model Post { id String @id @default(uuid()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt title String description String category String users User[] @relation("UserPosts") // 关联名称与User模型保持一致 }
修改后执行命令更新数据库:
npx prisma migrate dev
如果你的实际需求是一对多(一篇文章属于一个用户,一个用户有多篇文章),应该调整为:
model User { id String @id @default(uuid()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt email String? @unique image String? role Role @default(USER) posts Post[] } model Post { id String @id @default(uuid()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt title String description String category String userId String? // 外键字段 user User? @relation(fields: [userId], references: [id]) // 关联到User的id字段 }
2. 修正Pothos的关联字段映射
根据修正后的Prisma模型,调整Post.ts的字段定义:
- 多对多场景:
import { builder } from "../builder"; import { prisma } from "../builder"; // 确保导入同一个prisma实例 builder.prismaObject("Post", { fields: (t) => ({ id: t.exposeID("id"), title: t.exposeString("title"), description: t.exposeString("description"), category: t.exposeString("category"), users: t.relation("UserPosts"), // 与Prisma关联名称一致 }), }); builder.queryField("posts", (t) => t.prismaField({ type: ["Post"], resolve: (query, _parent, _args, _ctx, _info) => prisma.post.findMany({ ...query, }), }) );
- 一对多场景:
builder.prismaObject("Post", { fields: (t) => ({ // 其他字段... user: t.relation("user"), // 对应Post模型里的user字段 }), });
3. 解决查询返回空数组的问题
- 检查数据库关联数据:确保Post和User已经通过中间表(多对多)或外键(一对多)建立关联。可以用
npx prisma studio打开可视化界面,手动添加关联数据,或通过代码插入:
// 多对多关联示例 await prisma.post.update({ where: { id: "1" }, data: { users: { connect: { id: "你的用户ID" }, }, }, }); // 一对多关联示例 await prisma.post.update({ where: { id: "1" }, data: { userId: "你的用户ID", }, });
- Pothos的
prismaField会自动通过...query处理关联预加载,只要模型和字段定义正确,就能返回关联数据。
4. 解决"Duplicate typename: Another type with name Query already exists"错误
这个错误是重复定义了Query根类型导致的,按以下步骤排查:
- 确保全局只有一个
builder实例,所有文件导入同一个builder.ts中的实例 - 在
builder.ts中只定义一次Query根类型:
// builder.ts export const builder = new SchemaBuilder({ /* 配置 */ }); builder.queryType({}); // 仅调用一次
- 检查所有文件,不要重复调用
builder.queryType()或重复生成Schema
修正后的查询示例
- 多对多场景:
query MyQuery { posts { title id users { email id role } } }
- 一对多场景:
query MyQuery { posts { title id user { email id role } } }
内容的提问来源于stack exchange,提问作者Michael
相关产品推荐
相关产品推荐

