【发布时间】:2022-01-08 19:17:45
【问题描述】:
我正在使用 prisma 和 postgres 制作一个 Next JS 应用程序。
我有 2 个表:User 和 Profile
它们的棱镜模式结构如下:
model User {
id String @id @default(cuid())
name String?
email String? @unique
emailVerified DateTime?
image String?
// foreign keys
sessions Session[]
profile Profile?
}
model Profile {
id Int @id @default(autoincrement())
isAdmin Boolean @default(false)
firstName String
lastName String
email String @unique
phone String
address String
gender String
image Bytes
guardianName1 String
guardianPhone1 String
guardianRelation1 String
guardianName2 String?
guardianPhone2 String?
guardianRelation2 String?
guardianName3 String?
guardianPhone3 String?
guardianRelation3 String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
// foreign keys
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
userId String @default(cuid()) // relation scalar field (used in the `@relation` attribute above)
requests Request[]
}
我还使用next-auth 作为此应用程序的身份验证部分。因此,当用户注册并通过电子邮件验证时,next-auth 本身会将用户的记录添加到 User 表中。
到这里为止,没有问题。
然后,当用户第一次打开他的仪表板时,他会看到一个要填写的表单,提交该表单后,需要在 Profile 表中插入一条记录。由于 Profile 和 User 表是链接的,因此它们也需要连接。
所以当用户提交个人资料详细信息表单时,我会这样做:
try {
const newProfileData = {
// other fields data here...
user: {
connect: { id: '1' } // where User table already has a record with - 'id': 1
}
};
const profile = await prisma.profile.create({ data: newProfileData, include: { user: true } });
if(profile) {
console.log("Created: ", profile);
res.status(200).json({ msg: 'Successfully Created Profile!' });
}
}
catch(err)
{
console.log(err);
}
但是在运行这段代码时,我得到了错误:
The change you are trying to make would violate the required relation 'ProfileToUser' between the `Profile` and `User` models.
...
code: 'P2014',
clientVersion: '2.30.3',
meta: {
relation_name: 'ProfileToUser',
model_a_name: 'Profile',
model_b_name: 'User'
}
如何解决? 我什至尝试了另一种方式(即更新现有用户并创建与其连接的个人资料记录):
const user = await prisma.user.update({
where: {
email: req.body.email,
},
data: {
profile: {
create: {
// data fields here... (without the user field)
},
},
},
});
但这也会产生同样的错误...
我想了解为什么会出现错误。这不是使用 prisma-client 为 1 对 1 关系创建记录的正确方法吗?
【问题讨论】:
-
1:1 的关系总是有问题的,在这种情况下完全没有必要。
profile中唯一不在user中的属性是isAdmin列。当然,除非您允许列name和email(两者都存在)不同,否则您会遇到另一组问题。 -
不,实际上 Profile 表的列比提到的要多得多(我没有写所有这些,而是写了 -
// other attributes here) -
您是否尝试过将您的
user: { connect: {id: '1'换成简单的userId: '1'并使用include: { user: false }?我想知道您对userId String @default(cuid())的定义是否会在您发出prisma.profile.create()时强制它生成一个与任何现有User都不对应的新随机ID。当您在创建过程中指定include: { user: true }时,它是否会尝试创建另一个新用户,并自动生成另一个id?
标签: postgresql next.js prisma next-auth