mysql - 在 Prisma 中创建或更新一对多关系
问题描述
我正在尝试更新 Prisma 中的一对多关系。我的架构看起来像这样
model A_User {
id Int @id
username String
age Int
bio String @db.VarChar(1000)
createdOn DateTime @default(now())
features A_Features[]
}
model A_Features {
id Int @id @default(autoincrement())
description String
A_User A_User? @relation(fields: [a_UserId], references: [id])
a_UserId Int?
}
我正在尝试向 id: 1 的用户添加一些新功能,或者如果它们已经存在则更新它们。
我正在尝试做类似的事情
const post = await prisma.a_User.update({
where: { id: 1},
data: {
features: {
upsert: [
{ description: 'first feature'},
{ description: 'second feature'}
]
}
}
})
编译器不高兴,它告诉我
Type '{ features: { upsert: { description: string; }[]; }; }' is not assignable to type '(Without<A_UserUpdateInput, A_UserUncheckedUpdateInput> & A_UserUncheckedUpdateInput) | (Without<...> & A_UserUpdateInput)'.
Object literal may only specify known properties, and 'features' does not exist in type '(Without<A_UserUpdateInput, A_UserUncheckedUpdateInput> & A_UserUncheckedUpdateInput) | (Without<...> & A_UserUpdateInput)'.ts(2322)
index.d.ts(1572, 5): The expected type comes from property 'data' which is declared here on type '{ select?: A_UserSelect; include?: A_UserInclude; data: (Without<A_UserUpdateInput, A_UserUncheckedUpdateInput> & A_UserUncheckedUpdateInput) | (Without<...> & A_UserUpdateInput); where: A_UserWhereUniqueInput; }'
(property) features: {
upsert: {
description: string;
}[];
}
我无法弄清楚如何去做,也无法在文档中找到明确的帮助。关于如何实现它或在哪里可以找到一些示例的任何想法?
解决方案
我根据您在评论中提供的说明提供我的解决方案。首先,我将对您的架构进行以下更改。
更改架构
model A_User {
id Int @id
username String
age Int
bio String @db.VarChar(1000)
createdOn DateTime @default(now())
features A_Features[]
}
model A_Features {
id Int @id @default(autoincrement())
description String @unique
users A_User[]
}
A_User
值得注意的是,和之间的关系A_Features
现在是多对多的。因此,一条A_Features
记录可以连接到多A_User
条记录(反之亦然)。
此外,A_Features.description
现在是唯一的,因此可以仅使用它的描述来唯一地搜索某个功能。
您可以阅读Prisma 关系指南以了解有关多对多关系的更多信息。
编写更新查询
同样,根据您在评论中提供的说明,更新操作将执行以下操作:
覆盖
features
记录中的现有内容A_User
。因此,任何以前features
的都将断开连接并替换为新提供的。请注意,前一个features
不会从A_Features
表中删除,但它们只会与 关系断开连接A_User.features
。创建表中尚不存在的新提供的特征
A_Features
,并连接表中已存在的提供的特征A_Features
。
您可以使用两个单独的update
查询来执行此操作。第一次更新将断开所有先前连接features
的提供的A_User
. 第二个查询将连接或创建新提供features
的A_Features
表。最后,您可以使用事务 API来确保两个操作按顺序一起发生。事务 API 将确保如果两个更新中的任何一个出现错误,那么两个更新都会失败并被数据库回滚。
//inside async function
const disconnectPreviouslyConnectedFeatures = prisma.a_User.update({
where: {id: 1},
data: {
features: {
set: [] // disconnecting all previous features
}
}
})
const connectOrCreateNewFeatures = prisma.a_User.update({
where: {id: 1},
data: {
features: {
// connect or create the new features
connectOrCreate: [
{
where: {
description: "'first feature'"
}, create: {
description: "'first feature'"
}
},
{
where: {
description: "second feature"
}, create: {
description: "second feature"
}
}
]
}
}
})
// transaction to ensure either BOTH operations happen or NONE of them happen.
await prisma.$transaction([disconnectPreviouslyConnectedFeatures, connectOrCreateNewFeatures ])
如果您想更好地了解如何工作connect
,请阅读文档中Prisma 关系查询文章的嵌套写入部分。disconnect
connectOrCreate
推荐阅读
- android - 模块的元数据版本不匹配...在 ionic3 中找到预期版本 3
- java - Java 什么时候读取方法字节码?
- java - junit中的TestRestTemplate
- rxjs - RxJS 6 静态合并在哪里?
- asp.net-mvc - 自定义编辑器用于模板和 htmlAttributes
- markdown - 带有 .md 的 Jekyll + Github 页面返回 404
- api - JwtSecurityToken 过期日期相隔两个小时
- java - 如何在通话仍处于活动状态时隐藏拨号器意图
- java - 使用 JAR 从 FIRESTORE DB 中删除文档失败
- user-interface - 在 Unity 编辑器中放大关节锚图标