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?
If you're trying to add new features, and update specific ones, you would need to specify how Prisma can find an old feature (if it exists) to update that one.
I imagine the object you're passing to data takes a different set of options than you are specifying; if you can inspect the TypeScript types, Prisma will tell you exactly what options are available.
The table contains the values suggested in the original INSERT command (that conflicted with the existing table values). Note: If you are connecting to your database with Prisma client, you can perform upsert operations using the dedicated upsert operation. For our examples, suppose that we have a table called director.
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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With