首页 > 解决方案 > Unknown argument error when creating record

问题描述

I'm encountering some interesting behaviour when using Prisma ORM. It is related to Prisma's generated types, and I've been skimming the docs trying to find out more, but there doesn't seem to be much info about generated types in there (please correct me if I'm mistaken). Here's the behaviour:

Say I have a model with two 1-1 relations (Profile in the example below):

datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}

generator client {
  provider = "prisma-client-js"
}

model User {
  id      Int      @id @default(autoincrement())
  name    String
  profile Profile?
}

model Profile {
  id      Int    @id @default(autoincrement())
  name    String
  userId  Int?
  user    User?  @relation(fields: [userId], references: [id])
  photoId Int?
  photo   Photo? @relation(fields: [photoId], references: [id])
}

model Photo {
  id      Int      @id @default(autoincrement())
  url     String
  profile Profile?
}

The following code works when creating a new profile:

const user = await prisma.user.create({ data: { name: "TestUser" } });    
const profile = await prisma.profile.create({
  data: {
    name: "TestProfile",
    user: { connect: { id: user.id } },
    photo: { create: { url: "http://example.com/img" } },
  },
});

... but this fails with an error:

const user = await prisma.user.create({ data: { name: "TestUser" } });
const profile = await prisma.profile.create({
  data: {
    name: "TestProfile",
    userId: user.id,
    photo: { create: { url: "http://example.com/img" } },
  },
});

The error is:

Unknown arg userId in data.userId for type ProfileCreateInput. Did you mean user? Available args:
type ProfileCreateInput {
  name: String
  user?: UserCreateNestedOneWithoutProfileInput
  photo?: PhotoCreateNestedOneWithoutProfileInput
}

Why is the second create-profile code invalid?

标签: prismaprisma2

解决方案


createPrisma 本质上为查询生成两种类型定义。这是用一种XOR类型实现的,它确保只有两个定义中的一个被完全指定并传递给查询:

export type ProfileCreateArgs = {
  ...
  data: XOR<ProfileCreateInput, ProfileUncheckedCreateInput>;
}

这些定义被称为检查和未检查,前者使用嵌套字段,后者使用原始 id:

export type ProfileCreateInput = {
  id?: number;
  ...
  user?: UserCreateNestedOneWithoutProfileInput;
  photo?: PhotoCreateNestedOneWithoutProfileInput;
}

export type ProfileUncheckedCreateInput = {
  id?: number;
  ...
  userId?: number;
  photoId?: number;
}

这基本上意味着您要么将所有引用提供为connectcreate关系(选中)或作为原始 ID(未选中)。您不能混合样式,这是不支持的。


推荐阅读