I'm using Prisma (https://www.prisma.io) as ORM. I want to check for duplicates when store data and, if not exists, create a new record.
I thought I could do that with upsert method provided by Prisma and available in the generated client, but the where clause of that method only works with id (or @unique fields), but if the record doesn't exist, there isn't any id to provide.
I provide an example of the problem.
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
}
seed.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();
After creation there is a database with three Systems without performances. I'm trying to insert a new SystemPerformance if there aren't any that have same date and same System. I have tried
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
}
})
But an exception is thrown:
UnhandledPromiseRejectionWarning: Error: Variable '$where' expected value of type 'SystemPerformanceWhereUniqueInput!' but got: {"system":{"name":'s1'},"date":"2019-03-12T00:01:06.000Z"}. Reason: 'system' Field 'system' is not defined in the input type 'SystemPerformanceWhereUniqueInput'
The only solution I have found is check for existence and then update or create, but I wanted to do it with 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
}
})
Is there a way to do that with upsert?
The fields in where
need to be unique.
If you can make some field, let's say date
@unique (date: DateTime! @unique
), and use that for your where in the upsert, I think it would work (tested on my local)