如何在没有 ID 的情况下更新 Prisma 中的新记录?



我正在使用Prisma(https://www.prisma.io)作为ORM。我想在存储数据时检查重复项,如果不存在,请创建新记录。

我想我可以使用 Prisma 提供的 upsert 方法并在生成的客户端中可用,但该方法的 where 子句仅适用于 id(或 @unique 字段),但如果记录不存在,则没有任何 id 可以提供。

我提供了这个问题的一个例子。

datamodel.prisma

type System {
id: ID! @unique
performances: [SystemPerformance!]! @relation(name: "PerformanceBySystem" onDelete: CASCADE)
name: String! @unique
}
type SystemPerformance {
id: ID! @unique
system: System! @relation(name: "PerformanceBySystem")
date: DateTime!
perf1: Float
perf2: Float
}

种子.js

const { prisma } = require('./generated/prisma-client');
async function main(){
await prisma.createSystem({
name: 's1',
});
await prisma.createSystem({
name: 's2',
});
await prisma.createSystem({
name: 's3',
});
}
main();

创建后,有一个包含三个没有性能的系统的数据库。如果没有具有相同日期和相同系统的系统性能,我正在尝试插入新的系统性能。我试过了

const { prisma } = require('./prisma/generated/prisma-client');
const perf = await prisma.upsertSystemPerformance({
where: {
system: {name: 's1'},
date: "2019-03-12T00:01:06.000Z"
},
update: {
perf1: 13.45,
perf2: 18.93
},
create: {
system: {
connect: { name: 's1' }
},
date: "2019-03-12T00:01:06.000Z",
perf1: 13.45,
perf2: 18.93
}
})

但是抛出了一个异常:

UnhandledPromiseRejectionWarning: 错误: 变量"$where"的预期值类型为"系统性能在哪里唯一输入!"但得到:{"系统":{"名称":'s1'},"日期":"2019-03-12T00:01:06.000Z"}。原因:"系统"字段"系统"未在输入类型"系统性能在哪里唯一输入"中定义

我找到的唯一解决方案是检查是否存在,然后更新或创建,但我想使用 upsert 来做到这一点。

let check = await prisma.$exists.SystemPerformance({
system: {name: 's1'},
date: "2019-03-12T00:01:06.000Z"
});
let perfo;
if (check){
const sysPerf = await prisma.systemPerformances({where:{system: {name: 's1'}, date: "2019-03-12T00:01:06.000Z"}})
.$fragment(`
{
id
}
`);
perfo = await prisma.updateSystemPerformance({
where: {id: sysPerf[0].id},
data: {
perf1: 13.45,
perf2: 18.93
}
})
}
else {
perfo = await prisma.createSystemPerformance({
system: {
connect: { name: 's1' }
},
date: "2019-03-12T00:01:06.000Z",
perf1: 13.45,
perf2: 18.93
}
})

有没有办法用更新来做到这一点?

where中的字段必须是唯一的。

如果你能做一些字段,比如说date@unique(date: DateTime! @unique),并将其用于你在 upsert 中的位置,我认为它会起作用(在我的本地测试)

如果你仍然在这里没有答案,我使用了@Antoine的答案和另一个SO答案的组合:

model Likes {
id         String     @id @unique @default(uuid())
user_id    String
tag        String
auth_user  AuthUser   @relation(references: [id], fields: [user_id], onDelete: Cascade)
@@unique([user_id, tag], name: "user_id_tag")  // <-- this is the unique constraint
@@index([user_id])
@@map("likes")
}

然后我能够通过以下内容更新插入:

prisma.likes.upsert({
where: {
user_id_tag: { // <-- And this bit is important
user_id: user.userId,
tag: tag.tag
}
},
update: {},
create: tag
})
where: {
id: sysPerf[0].id ? sysPerf[0].id : 0
},

如果使用Mongo则可以使用 bson-objectid 包添加 ObjectId:

import ObjectId from "bson-objectid";
providers: {
upsert: data.item?.map((item: Prisma.ItemCreateInput) => ({
where: {
id: item.id || ObjectId().toString(),
},
update: {
// ...data
},
create: {
// ...data
},
})),
},
}

否则,您将需要提供自己的 uuid 或将要传递的唯一标识符。

另请参阅 https://github.com/prisma/prisma/issues/6718

最新更新