Cascading Deletes #1262
Comments
I feel that just a true/false setting is oversimplifying the cases this needs to cover. There is a reason why cascading referential constraints are not a simple binary switch. For example, I want to prevent the delete if there are children linked to it (compared to Ideally, I could also set the default behavior, but explicitly specifying it is fine for now. |
All of these cases are handled by the proposal:
|
I added some detail to my answer. I cannot prevent the delete it the relation is not required. So it's only about that first point now. Compare it to folders and files. I can create an empty folder (files are not required), and I can delete an empty folder, but when there are files in the folder, I can't delete folder because I get an error that it's not empty. This is actually a pattern that is very common. And making it part of the cascading configuration would be a lot more consistent than having to write a permission query for it. |
That's a great point! Let's examine the different cases. In a parent-child relationship:
To handle all cases we need to introduce three different settings:
The most straight-forward option is to use relational terminology directly: type Blog @model {
id: ID! @isUnique
comments: [Comment!]! @relation(name: "Comments", onDelete: CASCADE)
owner: User! @relation(name: "BlogOwner", onDelete: SET_NULL)
}
type Comment @model {
id: ID! @isUnique
blog: Blog! @relation(name: "Comments", onDelete: NO_ACTION)
author: User @relation(name: "CommentAuthor", onDelete: NO_ACTION)
}
type User @model {
id: ID! @isUnique
comments: [Comment!]! @relation(name: "CommentAuthor", onDelete: CASCADE)
blog: Blog @relation(name: "BlogOwner", onDelete: CASCADE)
} If anyone can come up with better terminology I'd be happy to adopt it. We decided not to implement the NO_ACTION option until we see a real need for it. |
Checking in to see what the timeframe looks like for this. Any updates? |
This feature is currently work in progress and will rolled out soon 🙂 |
The second part of the implementation is now done and we will release this shortly. We decided to not implement NO_ACTION for now. If we get the feeling that there is a strong need for this we will add this later. For now SET_NULL is encoding the old behavior and CASCADE will try to delete connected nodes but still guarantee integrity rules specified by required relations in the schema. |
Will it work for nested connections like this?
Can't wait to try this feature! 🙂 |
@emipc, you can try it out locally right now 🙂 Here's more information about running the latest changes in the unstable channel. |
I've installed prisma/1.2.0-beta.5 and tried it with the previous schema. Unfortunately, I got this error:
This is my resolver:
And this is the mutation I'm running:
Similar error happens if I try to delete a CourseSection, so it's not related to nested connections. Am I doing something wrong? |
Well, as usually, after doing a Nice job, this is a very cool feature 🙂 |
Glad to hear it works, but trying to reproduce your issue already showed me another small bug. Changing the onDelete argument does not seem to be picked up at the moment when deploying changes. |
Then I'm glad to be a useful beta tester! |
This was released in |
UPDATE: We will adopt the terminology given in the proposal below
Cascading deletes is an essential tool to maintain referential integrity.
Definition in types.graphql
This is a typical one-many relationship where a
Comment
cannot exist without a Blog.A comment can have an author, but doesn't have to.
Blog
is deleted, allComment
s associated through thecomments
field are deleted.Comment
is deleted, the relatedBlog
will not be deleted, but theComment
is removed from thecomments
field. Same for relatedUser
if any.User
is deleted, all relatedComment
s are deleted. If there is a relatedBlog
it is deleted together with all related comments.Required relations and Cascading Delete
Relation fields can be required. If a non-list relation field is required and the related node is deleted there are two cases:
cascadeDelete: true
both nodes are deletedcascadeDelete: false
no nodes are deletedEffect on AddTo and RemoveFrom relations
Cascading Delete only affects mutations that delete a node.
If an AddTo and RemoveFrom relation would result in a required relation without a node, it will be blocked no matter what the cascadingDelete setting is.
Cascading Update
In the future we will introduce the ability to use a custom id for nodes. We might also make it possible to change the id of a node with the Update mutation. If we do so, we will introduce a setting for cascadeUpdate that will control if the new id should be propagated to relations or the relations should be broken.
Todo
The text was updated successfully, but these errors were encountered: