New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Prisma Client: When relationMode="prisma"
Deleting an item in an Implicit Many-to-Many does not delete the corresponding entry in the implicit pivot table
#16390
Comments
I assume you are using the |
I was curious and found the full schema at https://github.com/Hardel-Labs/labs.hardel.io/blob/beta/prisma/schema.prisma generator client {
provider = "prisma-client-js"
previewFeatures = ["referentialIntegrity"]
}
datasource db {
provider = "mysql"
url = env("DATABASE_URL")
referentialIntegrity = "prisma"
} |
I could reproduce the issue generator client {
provider = "prisma-client-js"
previewFeatures = ["referentialIntegrity"]
}
datasource db {
provider = "mysql"
url = env("DATABASE_URL")
referentialIntegrity = "prisma"
}
model Item {
id Int @id @default(autoincrement())
categories Category[]
createdAt DateTime @default(now())
updatedAt DateTime? @updatedAt
}
model Category {
id Int @id @default(autoincrement())
items Item[]
createdAt DateTime @default(now())
updatedAt DateTime? @updatedAt
} import { PrismaClient } from "@prisma/client";
async function main() {
const prisma = new PrismaClient();
// Start from a clean state
await prisma.item.deleteMany({});
await prisma.category.deleteMany({});
await prisma.$executeRaw`TRUNCATE TABLE \`_CategoryToItem\`;`;
// Create one category
const category = await prisma.category.create({
data: {},
});
console.log("create category:", { category });
// Create one item linked to the category
const item = await prisma.item.create({
data: {
categories: {
connect: {
id: category.id,
},
},
},
include: {
categories: true,
},
});
console.log("create item:", { item });
// Check the pivot table entries
const pivotTable = await prisma.$queryRaw`SELECT * FROM \`_CategoryToItem\`;`;
console.log("pivot table:", { pivotTable });
await prisma.item.delete({
where: {
id: item.id,
},
});
console.log(`deleted: item id ${item.id}`);
// Item query now returns null
const getItem = await prisma.item.findUnique({
where: {
id: item.id,
},
include: {
categories: true,
},
});
console.log("item now:", { getItem });
// Category has no items
const getCategory = await prisma.category.findUnique({
where: {
id: category.id,
},
include: {
items: true,
},
});
console.log("category now:", { getCategory });
// Everything looks good but....
// Let's check the pivot table
// :warning: The entry was not deleted :warning:
const pivotTableNow =
await prisma.$queryRaw`SELECT * FROM \`_CategoryToItem\`;`;
console.log("pivot table now:", { pivotTableNow });
prisma.$disconnect();
}
main(); output of
This code shows that the implicit pivot table still contains the relationship between the Removing |
Thank you, I was not too present to answer your question. As it was indicated by PlanetScale of indicated : I added it without really understanding what it could be. |
relationMode="prisma"
Deleting an item in an Implicit Many-to-Many does not delete the corresponding entry in the implicit pivot table
I can confirm this is happening for me too. Unfortunately, I cannot get rid of |
This error can be more problematic than it seems. If you retrieve relation items like this:
the pivot table will return all the items that have id, even the ones that no longer exist on the original table (not the pivot). To solve this problem, as a patch, you need to include another field that won't exist in the pivot table, for example:
|
Yes, this is happening for me as well and causes a lot of headaches. Thanks for the (albeit imperfect, of course) workaround @edmbn |
Is this issue in any roadmap version? Tests where made and there even exist a draft pull request with fixes. Looks like it was on the 4.9.0 milestone but that never happened. |
这个问题 现在还存在 Edit (translation): "That's still a problem." |
I just realized this is a thing the hard way. Please address this as soon as possible + provide a way to fix the existing data that have been affected by this (if even possible) |
As a workaround if you're trying to delete relationships between many-to-many tables, you can do this with $executeRaw if you find the name of the generated join table (for example. by looking in Planetscale). If you've got two tables, "item" and "category" then it'll be _ItemToCategory The generated table has two columns, A and B. Each column is the relation id. You can manually delete the records in the join table using $executeRaw For example, to completely clear the join table of all records you can perform: await prisma.$executeRaw Or just clear all join records for a single Category await prisma.$executeRaw |
This is happening for my team too. It can be a source of many bugs if we are not careful with how we write our queries. We will implement a workaround for now by disconnecting all m-n relations from a record before deleting it. This issue has been open since over a year now, can it please be addressed soon? |
Could a member from the Prisma team please take a look at this. This is a serious flaw. |
Bug description
The bug is quite simple to understand.
To facilitate the reading of this bug report I put an example diagram.
To explain how this bug appear, I will proceed step by step.
We see that in the associative table between Categories and Items that a record row is present but empty.
So basically the data is not deleted in cascade.
We end up with tons of empty lines that point to a non-existent element.
How to reproduce
We see that in the associative table between Categories and Items that a record row is present but empty.
Expected behavior
The data must be deleted if one of the two fields of the associative table is missing.
Prisma information
Environment & setup
Prisma Version
The text was updated successfully, but these errors were encountered: