You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 02:50:53