How to only foreign key in Prisma not the whole object - node.js

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.

Related

Prisma and mongodb optional unique field throws "Unique constraint" error when empty

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

Prisma don't let me make a relation to the same table

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

Prisma not deleting because it depends on nonexistent record

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])

Prisma postgres - Unique constraint failed on the fields: (`id`)

For some reason I'm getting the error Unique constraint failed on the fields: (id) when trying to create a new Artist document.
Below is the function I'm calling.
async create(createArtistInput: CreateArtistInput): Promise<Artist> {
console.log(createArtistInput, 'create artist input')
const slug = slugify(createArtistInput.name, {
replacement: '-',
strict: true,
})
return this.db.artist.create({
data: {
name: createArtistInput.name,
spotifyArtistId: createArtistInput.spotifyArtistId,
spotifyArtistName: createArtistInput.spotifyArtistName,
slug,
},
})
}
The console log prints the following response, so I don't understand why the unique constraint of id is failing, as I'm not passing one in. I'm letting the prisma schema handle that.
{
name: 'twofiveone',
spotifyArtistId: '5Fex9xz9rkPqQqMBVtuIrE',
spotifyArtistName: 'twofiveone'
} create artist input
Here is the prisma schema if needed
model Artist {
id Int #id #default(autoincrement())
name String
slug String?
createdAt DateTime #default(now())
updatedAt DateTime #updatedAt
spotifyArtistId String?
spotifyArtistName String?
}
Does anyone have any idea what is happening? It's as if I can't create and new artists for some reason.
Autoincrement creates its own sequence starting from 1 which you can read more about here.
If you add random records with the id, then Postgres doesn't know that and it tries to start from 1. If 1 is already present, then it will throw an error.
So the best practice, in this case, is always let the database generate the id for you instead of you adding it manually. Hope this helps
The most likely reason for this is that somehow rows have been manually added with the id 0 at the start.

Prisma type-checking fails for destructured and appended objects

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!

Resources