删除ndb中的挂钩PolyModel子类不会执行

时间:2014-05-28 20:53:01

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

我正在使用ndb.polymodel.PolyModel为不同类型的社交媒体帐户建模。删除帐户后,必须进行一些清理(取决于子类)。

我尝试在子类上实现_pre_delete_hook,但它永远不会被执行。将完全相同的钩子添加到其父类时,执行:

class Account(polymodel.PolyModel):
    user = ndb.KeyProperty(kind=User) 

    @classmethod
    def _pre_delete_hook(cls, key):
        # Works as expected
        pass

class TwitterAccount(Account):
    twitter_profile = ndb.StringProperty()

    @classmethod
    def _pre_delete_hook(cls, key):
        # Never gets called
        pass

t_account = TwitterAccount.get_by_id(1)
t_account.key.delete()

对我来说似乎很奇怪,因为我希望子类钩子覆盖它的父级。或者这是预期的行为?


解决方案: 我错过了在delete(不是模型实例)上发生Key操作的事实。密钥本身只知道最顶层的类的名称(在这种情况下为Account)。

我最终在子类上定义了一个自定义_delete_hook实例方法。当_pre_delete_hook被调用时,我获取实体,然后检查它的类是否有一个特定的delete_hook来执行:

    # In subclass:
    def _delete_hook(self):
        # Do stuff specific for this subclass
        return

    # In parent class
    @classmethod
    def _pre_delete_hook(cls, key):
        s = key.get()
        if hasattr(s, '_delete_hook'):
            s._delete_hook()

1 个答案:

答案 0 :(得分:0)

不幸的是,这是预期的非显而易见的行为

当您使用key拨打PolyModel删除时,您只在父类上调用删除。

看看你正在调用删除键,你会看到Kind是父模型。然后它通过Kind - >查找班级。类地图,它将为您提供Account课程。阅读PolyModel的工作原理。它将所有Account子类存储为Account,并具有描述继承heirarchy的额外属性。因此,对Account的查询将返回所有Account子类,但TwitterAccount上的查询将仅返回该子类。

调用ndb.delete_multi也不起作用。

如果你想要一个特定的PolyModel子类pre delete hook来运行,你必须在子类中添加一个delete方法,然后调用它,然后可以调用子类_pre_delete_hook(并且可以调用super)。

但如果您直接致电key.delete

,这会导致问题