Deleting node with required inverse edges

Hi,

Suppose we have the following schema

type Parent {
    children: [Child] @hasInverse(field: parent)
}

type Child {
   parent: Parent! 
}

If we delete an instance of a previously created parent, we’ll leave all its children with no parent while its required in the schema.

In this case, wouldn’t it be the role of Dgraph to also remove the children to make data comply with the user’s schema ?

I guess that this would required the query to be somehow recursive which doesn’t seem to be the current behavior. But still, the documentation is quite sparse about the details and make it hard to understand the behavior of data deletion.

Best would be to have control over this behaviour by the developer in the schema similar in nature to MySQL use of “ON DELETE” which has options to either set null, restrict, no action, cascade, and set default.

That would be interesting to see of that logic could be worked in as a schema directive on an edge.

When delete Parent, “set null” is current behaviour on child edge.

  • restrict would block delete if there were any children
  • no action would leave the inverse edge to the uid that is now empty
  • cascade delete children
  • set default would set children Parent’s to a staticly declared uid.
2 Likes

Thanks for your insight.

What I do for now, is implementing a custom “deepDeleteParent” mutation.
I catch the deleteParent mutation in a Business Logic Layer (build with gqlgen) and I do the deletion with a DQL request instead, trying to delete its orphan like this

upsert {
  query {
    id as var(func: uid({{.id}})) {                                                                                                                                                                            
          a as Parent.children          
          b as Parent.extra_node_to_delete                                                                                                                                                      
        }                                                                                                                                                                                                          
        all(func: uid(id,a,b)) {                                                                                                                                                                                 
            all_ids as uid                                                                                                                                                                                         
        }  
  }
  
  mutation {
    delete {
      uid(all_ids) * * .
    }
  }
}

I guess that I could also do that using a custom dql directive in the schema…