Ric*_*rdo 5 mysql typescript 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?
}
Run Code Online (Sandbox Code Playgroud)
我正在尝试向 id: 1 的用户添加一些新功能,或者更新它们(如果它们已经存在)。
我正在尝试做类似的事情
const post = await prisma.a_User.update({
where: { id: 1},
data: {
features: {
upsert: [
{ description: 'first feature'},
{ description: 'second feature'}
]
}
}
})
Run Code Online (Sandbox Code Playgroud)
编译器不高兴,它告诉我
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;
}[];
}
Run Code Online (Sandbox Code Playgroud)
我无法弄清楚如何做到这一点,也无法在文档中找到明确的帮助。关于如何实现它或者我可以在哪里找到一些例子有什么想法吗?
Tas*_*mam 12
我根据您在评论中提供的说明提供我的解决方案。首先,我将对您的架构进行以下更改。
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[]
}
Run Code Online (Sandbox Code Playgroud)
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 将确保如果两个更新中的任何一个出现错误,则两者都将失败并被数据库回滚。
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[]
}
Run Code Online (Sandbox Code Playgroud)
connect如果您想更好地了解,disconnect和 的工作原理connectOrCreate,请阅读文档中Prisma Relation 查询文章的嵌套写入部分。
的 TypeScript 定义prisma.a_User.update可以准确地告诉您它需要哪些选项。这会告诉您'features' does not exist in type错误发生的原因。我想您传递给的对象采用data与您指定的不同的选项集;如果您可以检查 TypeScript 类型,Prisma 会准确告诉您可用的选项。
如果您尝试添加新功能并更新特定功能,则需要指定 Prisma 如何找到旧功能(如果存在)来更新该功能。Upsert 不会按照您当前使用的方式工作;您需要向 upsert 调用提供某种标识符,以便确定您要添加的功能是否已存在。
https://www.prisma.io/docs/reference/api-reference/prisma-client-reference/#upsert
您至少需要create(如果该功能不存在,则传递哪些数据), update(如果该功能存在,则传递哪些数据),以及where(Prisma 如何找到您想要更新或创建的功能。)
还需要upsert多次调用;对应您想要更新或创建的每一项功能。在这种情况下,您可以将调用一起批处理Promise.all。
const upsertFeature1Promise = prisma.a_User.update({
data: {
// upsert call goes here, with "create", "update", and "where"
}
});
const upsertFeature2Promise = prisma.a_User.update({
data: {
// upsert call goes here, with "create", "update", and "where"
}
});
const [results1, results2] = await Promise.all([
upsertFeaturePromise1,
upsertFeaturePromise2
]);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
47829 次 |
| 最近记录: |