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

Prisma创建Friend时嵌套创建FriendUser失败问题求助

Prisma Upsert Friend时无法嵌套创建关联User的解决方法

问题背景

Prisma Schema

model Friend {
  id                 Int              @id @default(autoincrement())
  userId             Int
  friendId           Int
  addedAt            DateTime
  removedAt          DateTime?
  createdAt          DateTime         @default(now())
  updatedAt          DateTime         @updatedAt
  user               User             @relation("UserFriends", fields: [userId], references: [id])
  friendUser         User             @relation("FriendOfUsers", fields: [friendId], references: [id])

  @@unique([userId, friendId])
}

model User {
  id               Int               @id @default(autoincrement())
  name             String
  email            String?
  avatar           String?
  createdAt        DateTime          @default(now())
  updatedAt        DateTime          @updatedAt
  friends          Friend[]          @relation("UserFriends")
  friendOf         Friend[]          @relation("FriendOfUsers")
}

尝试的代码

用户尝试通过upsert创建Friend时嵌套创建关联User,但触发类型错误:

return await this.prisma.friend.upsert({
  where: {
    userId_friendId: {
      userId: user.id,
      friendId: friendUserId ?? 0
    }
  },
  update: {
    removedAt: null
  },
  create: {
    userId: user.id,
    alias: contact.name, // 注:Friend模型无此字段,需删除
    relationshipTypeId: (await this.getRelationshipType('Phone Number')).id, // 注:Friend模型无此字段,需删除
    addedAt: new Date(),
    friendUser: {
      create: {
        name: contact.name,
        avatar: contact.image
      }
    }
  }
});

错误信息

Type '{ userId: number; alias: string; relationshipTypeId: number; addedAt: Date; friendUser: { create: { name: string; avatar: string | null; }; }; }' is not assignable to type '(Without<FriendCreateInput, FriendUncheckedCreateInput> & FriendUncheckedCreateInput) | (Without<...> & FriendCreateInput)'.
  Types of property 'friendUser' are incompatible.
    Type '{ create: { name: string; avatar: string | null; }; }' is not assignable to type 'undefined'.

原因分析

你的Friend模型中,friendUser关联是通过显式定义的friendId外键字段建立的,这种场景下Prisma要求创建Friend时必须直接提供friendId的标量值,不支持通过friendUser.create的方式嵌套创建关联用户——嵌套创建关联仅适用于隐式外键(即模型中未显式定义外键字段,仅通过@relation注解关联的场景)。

解决方案

必须通过交互式事务分步处理,逻辑如下:

  1. 先判断目标用户是否存在,不存在则创建新用户
  2. 使用该用户的ID执行Friend的upsert操作

修正后的代码示例

return await this.prisma.$transaction(async (tx) => {
  // 1. 检查或创建关联的User
  let friendUser;
  if (friendUserId) {
    friendUser = await tx.user.findUnique({
      where: { id: friendUserId }
    });
  }
  // 未找到用户则创建新用户
  if (!friendUser) {
    friendUser = await tx.user.create({
      data: {
        name: contact.name,
        avatar: contact.image
      }
    });
  }

  // 2. 执行Friend的upsert操作
  return await tx.friend.upsert({
    where: {
      userId_friendId: {
        userId: user.id,
        friendId: friendUser.id
      }
    },
    update: {
      removedAt: null
    },
    create: {
      userId: user.id,
      friendId: friendUser.id,
      addedAt: new Date()
    }
  });
});

注:代码中已删除原代码里Friend模型不存在的alias和relationshipTypeId字段,若你的实际Schema中有这些字段,可重新添加。

内容的提问来源于stack exchange,提问作者Jeremy Belolo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 14:05:09