5
votes

How do I delete an entire ancestor tree via the API (Python protocol buffer) in Google Cloud Datastore?

For example, if I have entities stored in this structure: grandparent/parent/child, how can I delete the grandparent, and in so doing delete all the children and grandchildren of that "node"?

If I submit a delete request on the grandparent's key, the grandparent entity is deleted, but its children and grandchildren remain, and their path is still grandparent/parent/child, even though the grandparent entity was deleted.

1

1 Answers

10
votes

Deleting a parent entity will not delete any of the child entities. However, you can use an ancestor query to find the keys of all of the child entities and delete them as part of a single transaction. The steps would be:

  1. Begin transaction.
  2. Run a keys-only kindless ancestor query on the parent entity's key.
  3. Add each of the keys returned by #2 to the list of keys to delete.
  4. Commit the transaction.

Here's a partial code snippet:

# Create a transactional RunQueryRequest.
req = datastore.RunQueryRequest()
req.read_options.transaction = txn  # From previous BeginTransactionRequest.

query = req.query

# Add an ancestor filter.
key_filter = query.filter.property_filter
key_filter.property.name = '__key__'
key_filter.operator = datastore.PropertyFilter.HAS_ANCESTOR
path_element = key_filter.value.key_value.path_element.add()
path_element.kind = 'ParentKind'
path_element.name = 'parent-name'

# Make it a keys-only query.
query.projection.add().property.name = '__key__'

batch = self.datastore.run_query(req)
for entity_result in batch:
  # Add entity_result.entity.key to CommitRequest...