PrismaClientValidationError:ticket.create()调用无效问题求助
解决PrismaClientValidationError:调用prisma.ticket.create()时的唯一键验证问题
问题概述
调用prisma.ticket.create()时,不传userId参数会触发PrismaClientValidationError,提示InformationWhereUniqueInput类型的where参数必须包含id、userId或复合唯一键name_surname_phone_number_email中的至少一个;传入userId则程序正常运行。
报错信息
PrismaClientValidationError: Invalid ` prisma.ticket.create()` invocation in ./src/lib/server/ticket.ts:12:16 9 phone_number: string, 10 userId?: number 11 ) => → 12 prisma.ticket.create({ data: { title: "title", description: "description", createdBy: { connect: undefined }, info: { connectOrCreate: { where: { userId: undefined, name: "name", surname: "surname", email: "email", phone_number: "tel", ? id?: Int, ? name_surname_phone_number_email?: InformationNameSurnamePhone_numberEmailCompoundUniqueInput, ? AND?: InformationWhereInput | InformationWhereInput[], ? OR?: InformationWhereInput[], ? NOT?: InformationWhereInput | InformationWhereInput[], ? users?: UserNullableScalarRelationFilter | UserWhereInput | Null, ? tickets?: TicketListRelationFilter }, create: { name: "name", surname: "surname", email: "email", phone_number: "tel" } } } } }) Argument `where` of type InformationWhereUniqueInput needs at least one of `id`, `userId` or `name_surname_phone_number_email` arguments. Available options are marked with ?. at wn (./node_modules/.pnpm/@prisma+client@6.2.1_prisma@6.2.1/node_modules/@prisma/client/runtime/library.js:29:1363) at Vn.handleRequestError (./node_modules/.pnpm/@prisma+client@6.2.1_prisma@6.2.1/node_modules/@prisma/client/runtime/library.js:121:6982) at Vn.handleAndLogRequestError (./node_modules/.pnpm/@prisma+client@6.2.1_prisma@6.2.1/node_modules/@prisma/client/runtime/library.js:121:6663) at Vn.request (./node_modules/.pnpm/@prisma+client@6.2.1_prisma@6.2.1/node_modules/@prisma/client/runtime/library.js:121:6370) at async l (./1522/node_modules/.pnpm/@prisma+client@6.2.1_prisma@6.2.1/node_modules/@prisma/client/runtime/library.js:130:9617) at async <anonymous> (./test.ts:3:13) { clientVersion: '6.2.1' } Node.js v22.11.0
相关代码
运行文件(./test.ts)
import { createTicket } from './src/lib/server/ticket'; console.log(await createTicket('title', 'description', 'name', 'surname', 'email', 'tel'));
创建ticket的函数(./src/lib/server/ticket.ts)
export const createTicket = ( title: string, description: string, name: string, surname: string, email: string, phone_number: string, userId?: number ) => prisma.ticket.create({ data: { title, description, createdBy: { connect: userId ? { id: userId } : undefined }, info: { connectOrCreate: { where: { userId, name, surname, email, phone_number }, create: { name, surname, email, phone_number } } } } });
Prisma Schema(./prisma/schema.prisma)
generator client { provider = "prisma-client-js" previewFeatures = ["driverAdapters"] } datasource db { provider = "postgresql" url = env("DATABASE_URL") directUrl = env("DIRECT_URL") } model User { id Int @id @default(autoincrement()) username String? @unique password String role UserRole @default(USER) tickets Ticket[] @relation("CreatedBy") assignedTickets Ticket[] @relation("AssignedTo") info Information? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt } model Ticket { id String @id @default(nanoid()) title String description String status TicketStatus @default(PENDING) createdBy User? @relation("CreatedBy", fields: [userId], references: [id]) userId Int? assignedTo User? @relation("AssignedTo", fields: [operatorId], references: [id]) operatorId Int? infoId Int info Information @relation(fields: [infoId], references: [id]) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt closedAt DateTime? } model Information { id Int @id @default(autoincrement()) name String surname String phone_number String? email String? userId Int? @unique users User? @relation(fields: [userId], references: [id]) tickets Ticket[] @@unique([name, surname, phone_number, email]) } enum UserRole { USER OPERATOR ADMIN } enum TicketStatus { PENDING ONGOING COMPLETED }
解决方案
问题出在connectOrCreate的where条件构造上:当userId为undefined时,你传入的{ userId, name, surname, email, phone_number }会被Prisma忽略userId字段,剩下的字段没有被识别为有效的唯一键查询(必须明确指定复合唯一键的字段名)。
修改createTicket函数的info部分,根据userId是否存在,分别构造符合要求的唯一键查询条件:
export const createTicket = ( title: string, description: string, name: string, surname: string, email: string, phone_number: string, userId?: number ) => prisma.ticket.create({ data: { title, description, createdBy: { connect: userId ? { id: userId } : undefined }, info: { connectOrCreate: { // 根据userId是否存在,选择不同的唯一键查询条件 where: userId ? { userId } : { name_surname_phone_number_email: { name, surname, phone_number, email } }, // 创建Information时,如果有userId则关联 create: { name, surname, email, phone_number, ...(userId && { userId }) } } } } });
关键说明
- 当
userId存在时,直接用userId作为唯一键查询(因为Information模型中userId是唯一字段) - 当
userId不存在时,使用你定义的复合唯一键name_surname_phone_number_email来构造查询,明确告诉Prisma用这四个字段匹配已有记录 - 创建
Information时,若有userId,记得把它传入,建立和User的关联
这样修改后,无论是否传入userId,connectOrCreate的where条件都会符合Prisma的唯一键验证要求,不会再触发报错。
内容的提问来源于stack exchange,提问作者Sebastiano
相关产品推荐
相关产品推荐

