如何在Prisma中用预定义ID实现1对1关联的嵌套写入?
预定义User ID时嵌套创建关联对象的问题解决
问题描述
需要创建带预定义ID的User,同时嵌套事务性创建关联的UserAuthentication和UserProfile,但TypeScript报错Type 'xxx' is not assignable to type 'never',且必须手动重复传入userId。
原Prisma Schema
// This is your Prisma schema file, // learn more about it in the docs: https://pris.ly/d/prisma-schema generator client { provider = "prisma-client-js" } datasource db { provider = "mongodb" url = env("DATABASE_URL") } model User { id String emailAddress String createdAt DateTime @default(now()) updatedAt DateTime @default(now()) @updatedAt objectId String @id @default(auto()) @map("_id") @db.ObjectId profile UserProfile @relation(fields: [id], references: [userId]) authentication UserAuthentication @relation(fields: [id], references: [userId]) @@unique([id]) @@unique([emailAddress]) @@map("users") } model UserProfile { firstName String lastName String userId String objectId String @id @default(auto()) @map("_id") @db.ObjectId user User? @@unique([userId]) @@map("user-profiles") } model UserAuthentication { passwordHash String userId String objectId String @id @default(auto()) @map("_id") @db.ObjectId user User? @@unique([userId]) @@map("user-auths") }
原代码实现
context.prisma.user .create({ data: { id: userId, emailAddress: input.emailAddress.toLowerCase(), profile: { create: { userId, firstName: input.firstName, lastName: input.lastName } }, authentication: { create: { userId, passwordHash } }, createdAt, updatedAt: createdAt } })
解决方案
1. 修正Schema的关联定义
原Schema中反向关联(UserProfile.user、UserAuthentication.user)未明确指定关联关系,导致Prisma无法自动推断嵌套创建时的关联字段值。需要为反向关联补充@relation注解:
model UserProfile { firstName String lastName String userId String objectId String @id @default(auto()) @map("_id") @db.ObjectId // 补充反向关联的@relation,指定关联字段映射 user User @relation(fields: [userId], references: [id]) @@unique([userId]) @@map("user-profiles") } model UserAuthentication { passwordHash String userId String objectId String @id @default(auto()) @map("_id") @db.ObjectId // 补充反向关联的@relation,指定关联字段映射 user User @relation(fields: [userId], references: [id]) @@unique([userId]) @@map("user-auths") }
2. 简化创建代码,移除重复的userId
关联定义正确后,Prisma会自动将User的id填充到关联对象的userId字段,无需手动传入:
context.prisma.user.create({ data: { id: userId, emailAddress: input.emailAddress.toLowerCase(), profile: { create: { firstName: input.firstName, lastName: input.lastName } }, authentication: { create: { passwordHash } }, // 若无需自定义时间,可直接使用默认值,无需手动传入createdAt/updatedAt createdAt, updatedAt: createdAt } })
关于重复传入userId的疑问
你的预期是正确的:只要Schema关联定义完整,Prisma会自动推断并填充关联字段的值,不需要手动重复传入userId。之前必须手动传是因为反向关联未正确定义,导致Prisma无法识别关联关系,进而无法自动填充。
内容的提问来源于stack exchange,提问作者user19087793
相关产品推荐
相关产品推荐

