Google App Engine中的递归删除
我正在使用 Google App Engine 和 Django 1.0.2(还有 django-helper),想知道大家是怎么处理递归删除的。
假设你有一个模型,大概是这样的:
class Top(BaseModel): pass class Bottom(BaseModel): daddy = db.ReferenceProperty(Top)
现在,当我删除一个类型为 'Top' 的对象时,我希望所有关联的 'Bottom' 对象也能被删除。
目前的情况是,当我删除一个 'Top' 对象时,'Bottom' 对象却留在那儿,这样就会出现一些无处归属的数据。在查看数据存储时,我最终得到的是:
Caught an exception while rendering: ReferenceProperty failed to be resolved.
当然,我可以找到所有对象并逐个删除,但因为我的真实模型至少有 5 层深,所以我希望能有一种方法可以自动完成这个操作。
我找到了一篇关于 Java 的 文章,看起来这正是我想要的功能。
有没有人知道我怎么才能在 Django 中实现这种行为呢?
4 个回答
2
重新考虑一下数据结构。如果在记录的整个生命周期内,关系是不会改变的,你可以使用GAE的“祖先”功能:
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]
这样查询祖先=顶级时,就能找到所有层级的记录。所以删除它们会变得很简单。
descendants = list(db.Query().ancestor(top))
# should return [top] + middles + bottoms
2
其实这个行为是特定于GAE的。Django的ORM在执行.delete()时会模拟“删除时级联”的效果。
我知道这不是对你问题的直接回答,但也许可以帮助你避免去错误的地方寻找答案。
6
你需要手动实现这个功能,也就是说在删除父记录的同时,要查找并删除相关的记录。如果你想简化这个过程,可以在父类中重写 .delete() 方法,这样就能自动删除所有相关的记录。
为了提高性能,你几乎肯定需要使用只查询键的方式(这样可以直接获取要删除的实体的键,而不需要先获取和解码实际的实体),并且可以进行批量删除。比如:
db.delete(Bottom.all(keys_only=True).filter("daddy =", top).fetch(1000))