I'm using Prisma with an Express backend and React frontend. I was testing my delete request on Postman, and I keep getting this error:
"\nInvalid prisma.user.delete() invocation:\n\n\n An operation failed because it depends on one or more records that were required but not found. Record to delete does not exist."
I checked their docs, and unless I missed something—I can't really find much of an explanation. I'm also fairly new to relational databases, and this is the first time I've used Prisma.
My schema is incredibly long, so I'll post the relevant parts:
model User {
id String #id
email String #unique
firstName String
lastName String
approved Boolean #default(false)
usersDb Boolean #default(false)
volunteersDb Boolean #default(false)
createdAt DateTime #default(now())
updatedAt DateTime #updatedAt
avatarUrl String? #default("")
isActive Boolean #default(true)
lastLoggedIn DateTime #default(now())
role String #default("viewer")
volunteer Volunteer[]
}
model Volunteer {
id String #id #default(uuid())
userId String
dbUser User #relation(fields: [userId], references: [id])
My controller
const deleteUser = async (req, res) => {
const { id } = req.params;
await prisma.user.delete({
where: {
id,
},
});
Other than this, the table is behaving as expected and creating the relation to the Volunteer table. I feel like the error has something to do with that because I have another table without a relation, and the delete method works there.
Thanks in advance and happy to provide more info if necessary!
I figured this out and wanted to share. I was right, this had everything to do with the relation I'd created between the User and Volunteer table. When I tried to delete a record from the User table, I didn't tell Prisma what to do with the related records, so I got that error. I went back to my Volunteer model and made the relation fields optional, and the delete request worked. Here's the documentation on this, and here's my updated schema:
model User {
id String #id
email String #unique
firstName String
lastName String
approved Boolean #default(false)
usersDb Boolean #default(false)
volunteersDb Boolean #default(false)
createdAt DateTime #default(now())
updatedAt DateTime #updatedAt
avatarUrl String? #default("")
isActive Boolean #default(true)
lastLoggedIn DateTime #default(now())
role String #default("viewer")
volunteer Volunteer[]
}
model Volunteer {
id String #id #default(uuid())
userId String?
dbUser User? #relation(fields: [userId], references: [id])
Related
I have the following models in prisma schema:
model Order {
id String #id #default(auto()) #map("_id") #db.ObjectId
customer User #relation(fields: [customerId], references: [id])
customerId String #db.ObjectId
products Json
status String #default("pending")
paymentMethod String?
pixPayment Payment? #relation(name: "pixPayment", fields: [pixPaymentId], references: [id])
pixPaymentId String? #unique #db.ObjectId
creditCardPayment Payment? #relation(name: "creditCardPayment", fields: [creditCardPaymentId], references: [id])
creditCardPaymentId String? #unique #db.ObjectId
boletoPayment Payment? #relation(name: "boletoPayment", fields: [boletoPaymentId], references: [id])
boletoPaymentId String? #unique #db.ObjectId
total Float
createdAt DateTime #default(now())
##map("Orders")
}
model Payment {
id String #id #default(auto()) #map("_id") #db.ObjectId
paymentId Int
amount Float
paymentMethod String
customer User #relation(fields: [customerId], references: [id])
customerId String #db.ObjectId
payer Json?
installments Int #default(1)
status String #default("pending")
dateOfExpiration DateTime
dateApproved DateTime?
barcode String?
boletoUrl String?
pixQrCode String?
pixQrCodeBase64 String?
lastFourDigitsCard String?
cardHolder Json?
createdAt DateTime #default(now())
pixPaymentOrder Order? #relation("pixPayment")
creditCardPaymentOrder Order? #relation("creditCardPayment")
boletoPaymentOrder Order? #relation("boletoPayment")
##map("Payments")
}
I'm trying to create an Order document with the required fields (products, total, customerId), it works but only once, if I try to create another Order I get the error: "Unique constraint failed on the constraint: Orders_pixPaymentId_key". The pixPaymentId is an unique and optional field and in this case I'm not passing it.
Order create code:
const order = await prisma.order.create({
data: {
products,
total,
customerId: userId
},
select: {
id: true
}
});
I was expecting that would be possible to create multiple Orders documents without pixPaymentId as it is a OPTIONAL field, but I'm getting the Unique constraint error.
Prisma doesn't support unique and nullable feature yet.
For this case, we can only declare it as nullable and handle uniqueness manually. Same problem will occur when implementing unique and soft delete.
The reason why they don't support it because most database reject duplicate NULLs on unique constraint.
Follow this discussion: https://github.com/prisma/prisma/issues/3387
I'm starting Prisma for a project and I'm making the schema. I have a Customer table, and want to have a "referredBy" column, pointing to a customerId.
model Customer {
id Int #id #default(autoincrement())
uuid String #unique #default(uuid())
referralCode String?
referredBy Customer? #relation(fields: [referredById], references: [id])
referredById Int?
createdAt DateTime #default(now())
updatedAt DateTime #updatedAt
}
But it gives me an error.
Error validating field referreddBy in model Customer: The relation field referreddBy on Model Customer is missing an opposite relation field on the model Customer. Either run prisma format or add it manually.
It's not the first time I've encountered this. But usually it's for another table relation so I just add the opposite on the other table.
model Account {
id Int #id #default(autoincrement())
uuid String #unique #default(uuid())
**product Product #relation(fields: [productId], references: [id])**
customers Customer[]
}
I add
to the Product model:
Account Account[]
What kind of opposite relation field should I add?
Regards
I've just started learning nestjs and I'm using Prisma as my ORM, I've created two models (Employees, Clients), these models will contain foreign keys , the client will have the employee id and vice versa (a one-to-one relation), but as you will see in the models the employee will contain the whole Client "object", but what I want also is his client's id as an independent column :
this is the models:
model Employe {
id Int #id #default(autoincrement())
createdAt DateTime #default(now())
updated DateTime #updatedAt
email String #unique
hash String
nom String
prenom String
// I want the client ID here too
client Client?
##map("employes")
}
model Client {
id Int #id #default(autoincrement())
createdAt DateTime #default(now())
updated DateTime #updatedAt
email String #unique
hash String
nom String
prenom String
EmpId Int? #unique
emp Employe? #relation(fields: [EmpId], references: [id], onDelete: Cascade, onUpdate: Cascade)
##map("clients")
}
So is there any way ?
Framework: NestJS
ORM: Prisma
DB : Postgresql
Platform: Docker
In this link there is an example that can help you:
https://www.prisma.io/docs/guides/general-guides/database-workflows/foreign-keys/postgresql
I more or less understand what you mean. I don't understand why you don't set relation, but you can use this structure when creating a client or employe.
to create the employe
await prisma.employe.create({
data: {
email: 'blabla',
hash: 'balbla',
nom: 'blabla',
prenom: 'balbla',
clientId: 123,
include: {
client: {
...,
}
}
},
})
to create the client
await prisma.client.create({
data: {
email: 'blabla',
hash: 'balbla',
nom: 'blabla',
prenom: 'balbla',
employeId: 123,
include: {
employe: {
...,
}
}
},
})
The fields emp in the Client model and client in Employe model are relation fields so they won't exist in the database, they are just at the prisma level.
You only need to define the foreign key on one side of the relation - One to One relation Prisma reference
You could store clientId on the Employe model as well.
I'm using Prisma as a type-safe ORM within my typescript node environment. When I pass a restructured object to an update call
const params = {incorrect_param: true};
const data = await prisma.document.update({
where: { id },
data: {
...params,
// verified: true, // when this is uncommented, type-checking fails
},
});
it correctly highlights that params is not the right type to update the document. However when I uncomment the updated_at line, the errors go away and it fails to typecheck at all. Any idea what I am doing wrong here? The error occurs when any additional line is added beyond the restructured params object.
For context, my schema for document is as follows:
model identity_document_verification {
id BigInt #id #default(autoincrement())
created_at DateTime #default(now()) #db.Timestamptz(6)
updated_at DateTime #default(now()) #db.Timestamptz(6)
user_id String #db.Uuid
submission_id BigInt #unique(map: "idv_i_submission_id") #default(autoincrement())
verified Boolean?
submission submission #relation(fields: [submission_id], references: [id], onDelete: NoAction, onUpdate: NoAction)
user user #relation(fields: [user_id], references: [id], onDelete: NoAction, onUpdate: NoAction)
}
I'm on prisma#3.5.0 and next#11.1. Thank you in advance!
I would like to know how can I remove all items in table with Prisma2 and Jest ?
I read the CRUD documentation and I try with this :
user.test.js
....
import { PrismaClient } from "#prisma/client"
beforeEach(async () => {
const prisma = new PrismaClient()
await prisma.user.deleteMany({})
})
...
But I have an error :
Invalid `prisma.user.deleteMany()` invocation:
The change you are trying to make would violate the required relation 'PostToUser' between the `Post` and `User` models.
My Database
CREATE TABLE User (
id INTEGER PRIMARY KEY AUTO_INCREMENT NOT NULL,
name VARCHAR(255),
email VARCHAR(255) UNIQUE NOT NULL,
password VARCHAR(255) NOT NULL
);
CREATE TABLE Post (
id INTEGER PRIMARY KEY AUTO_INCREMENT NOT NULL,
title VARCHAR(255) NOT NULL,
createdAt TIMESTAMP NOT NULL DEFAULT now(),
content TEXT,
published BOOLEAN NOT NULL DEFAULT false,
fk_user_id INTEGER NOT NULL,
CONSTRAINT `fk_user_id` FOREIGN KEY (fk_user_id) REFERENCES User(id) ON DELETE CASCADE
);
schema.prisma
model Post {
content String?
createdAt DateTime #default(now())
fk_user_id Int
id Int #default(autoincrement()) #id
published Boolean #default(false)
title String
author User #relation(fields: [fk_user_id], references: [id])
##index([fk_user_id], name: "fk_user_id")
}
model User {
email String #unique
id Int #default(autoincrement()) #id
name String?
password String #default("")
Post Post[]
Profile Profile?
}
You are violating the foreign key constraint between Post and User.
You can not remove a User before deleting its Posts
beforeEach(async () => {
const prisma = new PrismaClient()
await prisma.post.deleteMany({where: {...}}) //delete posts first
await prisma.user.deleteMany({})
})
Or set CASCADE deletion on the foreign key,
this way when you delete a User its posts will be automatically deleted
This is another way to do it, this would remove all rows and its dependant rows, also would reset the ids. This way you can iterate over all the tables and order doesn't matter.
prisma.$executeRaw(`TRUNCATE TABLE ${table} RESTART IDENTITY CASCADE;`)