在事务之后调用NDB模型_post_delete_hook吗?或删除其引用实体时从blobstore清除blob的最佳方法

时间:2012-11-29 06:40:45

标签: google-app-engine blobstore app-engine-ndb

我正在实现一个文件存储系统,其中多个人可以共享上传到blobstore的文件,但是一旦他们全部删除了文件,它就会从blobstore中删除。

我使用引用计数实体执行此操作,当其计数设置为0时将删除。我还使用google.appengine.ext.ndb.blobstore中定义的BlobInfo ndb模型,因为我需要获取一堆BlobInfos几点,并希望能够异步地做到这一点。

当删除引用计数实体时,会调用其_post_delete_hook方法,我将其与BlobKey一起调用blobstore.delete_async,并且它还在ndb BlobInfo实例上调用BlobInfo._key.delete_async()。

class FileCounter(ndb.Model):
    count = ndb.IntegerProperty(default=1)
    @classmethod
    def _post_delete_hook(cls, key, future):
        blob_key = cls.blob_key_for_key(key)
        blobinfo_extension.delete(blobstore.BlobInfo.get(blob_key))

和blobinfo_extension.delete定义为:

@ndb.tasklet
def delete_async(blobinfo):
""" Delete both the blob info and the blob in the blobstore it refers to. """
    yield blobstore.delete_async(blobinfo.key()), blobinfo._key.delete_async()

def delete(blobinfo):
    delete_async(blobinfo).wait()

我正在获取计数实体,递减计数,然后检查它是否为0.如果为0,则删除它。这都是在交易中完成的。是否在事务之外调用_post_delete_hook方法?如您所见,它正在访问BlobInfo实体并删除需要跨组事务的实体。

我将尝试这个,看看它是否有效,但由于无法找到任何答案,我在此处发布了它,所以它可能在将来帮助其他人。

这是解决此问题的一个很好的解决方案,或者我应该在计数递减时只是“手动”清理blobstore / blobinfo?我想也许我在滥用post delete hook!

1 个答案:

答案 0 :(得分:2)

也许你可以在事务提交时使用ndb.get_context().call_on_commit(<callback>)做一些工作?您可以将它与常规_post_delete_hook结合使用,只需为提交后清理步骤添加实体。