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;`)
Related
I have a little problem on delete datas on my database.
I'm doing a app to create notes for movies (rating, comments, etc.) and I'm using two ways to set my database:
I created the table "users" manully using node and migrations:
const createUsers = `
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name VARCHAR,
email VARCHAR,
password VARCHAR,
avatar VARCHAR NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)
`
module.exports = createUsers;
And I created the tables 'movie_notes' and 'movie_tags' using the library 'knex' with migrations
exports.up = knex => knex.schema.createTable("movie_notes", table => {
table.increments("id");
table.text("title");
table.text("description");
table.integer("rating");
table.integer("user_id").references("id").inTable("users").onDelete("CASCADE");
table.timestamp("created_at").default(knex.fn.now());
table.timestamp("updated_at").default(knex.fn.now());
})
exports.down = knex => knex.schema.dropTable("movie_notes");
exports.up = knex => knex.schema.createTable("movie_tags", table => {
table.increments("id");
table.integer("movie_id").references("id").inTable("movie_notes").onDelete("CASCADE");
table.integer("user_id").references("id").inTable("users").onDelete("CASCADE");
table.text("name");
})
exports.down = knex => knex.schema.dropTable("movie_tags");
MY PROBLEM:
When I delete my notes, tags are also deleted (delete on cascade working very well), BUT when i delete a user who created notes and tags, these notes and tags aren't deleting (delete on cascade not working)
what can i do to fix it?
I expect delete all user notes and tags when i delete the user on database
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])
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.
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!