Recursive delete in google engine

I use the Google engine to work with django 1.0.2 (and django-helper) and wonder how people do recursive deletion. Suppose you have a model that looks something like this:

  class Top (BaseModel):
     pass

 class Bottom (BaseModel):
     daddy = db.ReferenceProperty (Top)

Now, when I delete an object of type "Top", I want all the associated "Bottom" objects to be deleted as well.

Like now, when I delete the "Top" object, the "Bottom" objects remain, and then I get data that does not belong anywhere. When accessing the data warehouse in the view, I get:

  Caught an exception while rendering: ReferenceProperty failed to be resolved. 

Of course, I could find all the objects and delete them, but since my real model is at least 5 levels, I hope that you can make sure that this can be done automatically.

I found this article on how it works with Java, and it looks like what I want too.

Does anyone know how I could get this behavior in django?

+6
python google-app-engine django
source share
4 answers

You need to implement this manually by viewing the affected records and deleting them at the same time as deleting the parent record. You can simplify this if you want by overriding the .delete () method of the parent class to automatically delete all related records.

For performance reasons, you almost certainly want to use key-only queries (allowing you to delete entity keys without deleting or decoding the actual objects), and the batch are deleted. For example:

db.delete(Bottom.all(keys_only=True).filter("daddy =", top).fetch(1000)) 
+6
source share

Actually, this behavior is specific to GAE. Django ORM models "ON DELETE CASCADE" on .delete ().

I know this is not the answer to your question, but perhaps it can help you look in the wrong place.

+2
source share

Revise the data structure. If the connection does not change during the life of the recording, you can use the GAE "ancestors" function:

 class Top(db.Model): pass class Middle(db.Model): pass class Bottom(db.Model): pass top = Top() middles = [Middle(parent=top) for i in range(0,10)] bottoms = [Bottom(parent=middle) for i in range(0,10) for middle in middles] 

Then the forcestor = top query will find all records from all levels. Therefore, they will be easy to remove.

 descendants = list(db.Query().ancestor(top)) # should return [top] + middles + bottoms 
+2
source share

If your hierarchy is just a small number of levels, then you can do something with a field that looks like a file path:

 daddy.ancestry = "greatgranddaddy/granddaddy/daddy/" me.ancestry = daddy.ancestry + me.uniquename + "/" 

kind of thing. You need unique names, at least unique among brothers and sisters.

The path identifier in object identifiers already does this, but IIRC is associated with entity groups that you are not recommended to use to express relationships in the data area.

Then you can build a query to return all granddaddy descendants using the original substring trick, for example:

 query = Person.all() query.filter("ancestry >", gdaddy.ancestry + "\U0001") query.filter("ancestry <", gdaddy.ancestry + "\UFFFF") 

Obviously, this is useless if you cannot put the pedigree in a 500-byte StringProperty.

+1
source share

All Articles