Hey @hirasaki1985 👋 ,
I reproduced this on my end as well (using MySQL) and it does seem unexpected. I'm going to convert this discussion into an issue where our engineering teams will pick it up for investigation.
upsert does not working with multi unique key.
node.js - How to upsert new record in Prisma without an ID? - Stack Overflow
node.js - Prisma: Update using "where" with non-unique fields? - Stack Overflow
.upsert when no way to track query/track unique identifier?
If you are still down here without an answer, I used a combination from @Antoine's answer and another SO answer:
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")
}
Then I was able to upsert via the following:
prisma.likes.upsert({
where: {
user_id_tag: { // <-- And this bit is important
user_id: user.userId,
tag: tag.tag
}
},
update: {},
create: tag
})
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)
In this case, you would need to use updateMany as you are using a non-unique field along with the unique one.
Apparently, as of Prisma version 4.5.0, there is a new feature allowing you to add non-unique fields to the unique where clause as long it contains at least one unique field.
Prisma realese 4.5.0
It's a preview feature so in order to enable it, add this to your shcema.prisma:
generator js {
provider = "prisma-client-js"
previewFeatures = ["extendedWhereUnique"]
}
And then your code sample will work.
return this.prisma.publication.update({
data,
where: {id, owner: user.id},
});
When a combination of fields is unique, Prisma will generate a new type for the where condition which is basically just the name of all the relevant fields appended together with _.
Take a look at the categoriesWhereUniqueInput to see what the name is. Most likely it is called user_id_hash or hash_user_id.
This is what the query will look like, roughly speaking:
const category = await prisma.categories.upsert({
where: {
user_id_hash: { // user_id_hash is the type generated by Prisma. Might be called something else though.
user_id: 1,
hash: "foo"
}
},
update: {
name: "bar",
},
create: {
hash: "foo",
name: "bar",
user_id: 1,
},
})
Just in case someone stumbles upon this: if you cannot find the option in the where clause to select by user_id_hash, then you need to first have declared the unique composite constraint in the table definition.
@@unique([fieldOne, fieldTwo])
After doing this you will be able to select in code, on the where condition: fieldOne_fieldTwo.