Cascading deletes is not implemented for the Mongo connector.
A validation should be added to the deploy step to make sure that it is not declared on the data model.
Note: Embedded types by their nature already have a cascading delete effect; deleting a top level type will of course also delete all its embedded types.
This should be in the docs, i just wanted to create an issue for.
https://github.com/domekol/prisma-mongodb-cascade-relation-bug
This should definitely be in the docs
@do4gr So will this be eventually implemented or is there a reason why?
Our implementation of Cascading Deletes in the SQL connectors relies on transactional guarantees across tables.
Mongo only started supporting cross-document transactions with 4.0. We are at the moment testing at what performance penalty enabling transactions on Mongo comes since this is a very new concept for them.
For what release will this be fixed?
Our prototype that implemented cascading deletes using transactions showed transaction errors (deadlocks etc. ) under heavy concurrency. We therefore cannot implement this feature at the moment.
Until we can we will therefore add an error during deployment to avoid confusion.
Reopening this issue as cascading deletes is not yet implemented for the Mongo connector. However, since we're not tackling this any time soon (see @do4gr's last comment), we're applying the on-hold
label for now.
are we talking weeks, months or years?
Do you propose a specific workaround?
I think this will probably take a couple of months until we can focus on this.
https://github.com/domekol/prisma-mongodb-cascade-relation-bug
@domekol is this issue fixed?
any updates regarding this issue, since I am making production ready app so any trick or the third party will also be better for me? @do4gr since its July 11
Is there any new news on this?
I believe this to be major. While there is no updates for this.
Until we can we will therefore add an error during deployment to avoid confusion.
What would be the recommended way to "cascade" deletion on a relation?
cheers
followup... https://github.com/prisma/prisma2/issues/267
Can someone point me to an alternative for now ?
currently, I am doing cascading deletes manually @omarragi
@developerk786 could you give us a simple example :)
it's simple it's my mistake i didn't explain much
let say we have this modal:
type User {
name: String!
posts: [Post!]!
}
type Post {
title: String!
body: String!
}
let's say we have to delete user with id: 1
// manually delete all relational fields
...otherCodes
const userId = param.userId
const posts = await prisma.posts()
posts.forEach(async post => {
await prisma.deletePost({ id: post.id })
})
// same for other fields lets say comments do the same as above
await prisma.deleteUser({ id: userId })
...restCodes
So if you have a nested relation like I did, it's gonna be a nightmare.
User => (Posts => Photos) + Comments + Favorites + Friends + ...
It will have to remove all of them when we remove a user. Otherwise they will become null and gather dust in the database for no reason.
Here is the similar code we had to put,
const result = await deleteAction({
where: {
id: args.id
}
}, info);
// TODO: use a queue instead of blocking all connection here
// What if the user has 100k logs on a instance? :/
await Promise.all([
logs && logs.length && (await deleteManyLogs(logs.map(log => ({
where: {
id: log.id
}
})))),
content && (await deleteContent({
where: {
id: content.id
}
})),
state && (await deleteState({
where: {
id: state.id
}
})),
source && (await deleteSource({
where: {
id: source.id
}
})),
]);
Then we were forced to refactor them a bit because we had to use them many times on many reducer, the code is kind of similar to this,
const deleteSingle = (group, mutation, info) => group && mutation({
where: {
id: group.id
}
}, info);
const groupMapped = group => group.map(single => ({
where: {
id: single.id
}
}));
const deleteMany = (group, mutation) => group && group.length && mutation(groupMapped(group));
// Run them
// we need to use/return this later
const result = await deleteSingle(args, deleteAction, info);
await Promise.all([
deleteMany(logs, deleteManyLogs),
deleteSingle(content, deleteContent),
deleteSingle(state, deleteState),
deleteSingle(state, deleteSource)
])
Maybe there is a better way to deal with this, who knows!
@developerk786 @entrptaher Yup, this is what I ended up doing too. It's a pain and more prone to errors. Would be nice if cascading deletes just worked as expected.
@entrptaher Your solution is better than mine =D, for now, we can do this but we can rely on prisma2 for future apps
I just released mongoke, it is a docker image that instantly serves your mongodb database via graphql and , contrary to prisma, works with existing databases, this means that you can directly insert and update the data in your database without worrying about corrupting prisma data model. It generates only graphql queries but you can easily attach other graphql services (to handle custom mutations) thanks to apollo federation.
It also has built in authorization using your jwt which means you can expose directly the service to the open world.
You should also remove it from docs
https://www.prisma.io/docs/datamodel-and-migrations/datamodel-MONGO-knun/
Most helpful comment
This should definitely be in the docs