如何使用Prisma ORM在一次查询中upsert多个字段?
我不想逐个使用upsert字段。我是否可以在一次查询中upsert所有字段?
如何使用Prisma ORM在一次查询中upsert多个字段?
我不想逐个使用upsert字段。我是否可以在一次查询中upsert所有字段?
目前在Prisma中无法执行此操作。虽然有createMany
、updateMany
和deleteMany
,但没有upsertMany
。(文档)
如果需要处理大量数据,则最有效的方法可能是:
prisma.$transaction([
prisma.posts.deleteMany({ where: { userId: 1 } }),
prisma.posts.createMany({
{ id: 1, title: 'first', userId: 1 },
{ id: 2, title: 'second', userId: 1 },
{ id: 3, title: 'third', userId: 1 },
}),
]);
不要插入具有唯一字段或已存在的ID字段的记录。仅受支持的数据库支持ON CONFLICT DO NOTHING。
deleteMany
然后createMany
可能不起作用,因为在尝试删除记录时存在关系约束。如果是这种情况,其中一个最佳答案对您来说将不起作用。updateMany
,但它不能按我们希望的方式进行更新--它可以将多条记录都更新为相同的值。所以不幸的是,您将不得不逐个更新记录。createMany
与skipDuplicates
标志一起使用时不会返回已创建的记录。如果是这样的话,我们可以找到返回记录与未创建的记录之间的差异,并更新未创建的记录。createMany
。如果你没有太多记录,最好使用prisma的upsert
。如果你有大量记录,那么也许这条路值得一试。function async upsertMerchant(merchants: Merchant[]) {
const merchantNames = merchants.map((merchant) => merchant.name)
const existingMerchants = await prisma.findMany({
where: {
name: {
in: merchantNames,
},
},
})
// For a quick lookup
const existingMerchantNames = new Set(existingMerchants.map((merchant) => merchant.name))
// This could be a reduce instead if you would like.
// I figured this is easier to follow for most folks.
const merchantsToCreate: Merchant[] = []
merchants.forEach((merchant) => {
if (existingMerchantNames.has(merchant.name)) {
await prisma.merchant.update({
where: {
name: merchant.name,
},
data: merchant,
})
} else {
merchantsToCreate.push(merchant)
}
})
await prisma.merchant.createMany({
data: merchantsToCreate,
skipDuplicates: true, // optional, there should not be duplicates, unless other code is racing you in concurrency.
})
// Optional if you want all the merchants back
// This should return all newly created and previously existing records with updated information.
return Prisma.merchants.findMany({
where: {
name: {
in: merchantNames,
},
},
})
}
正如我之前所说,如果你有大量的记录,使用createMany
可能会更高效,否则你只能逐个更新记录。如果你可以使用deleteMany
,那是一种更快、更高效的方法,但如果你有关联关系,可能不是一个选择。
如果你处理的记录不多,最简单的方法可能是循环遍历并利用Prisma的upsert
功能。这肯定会导致更易读的代码。
prisma.posts.findMany({ where: { userId: 1 }})
调用? - kevscriptdeleteMany
会级联删除其他表中的行吗? - devordem