如何在ndb的_put_hook中访问属性旧值,实现指定属性变更触发函数?
如何在NDB的_pre_put_hook中对比属性旧值并选择性触发函数
好问题!先直接给你结论:完全可以通过_pre_put_hook实现你的需求——核心思路是在钩子方法里从数据存储中拉取当前实例的旧版本,对比name属性的变化,再决定是否触发函数。
为什么需要拉取旧实例?
当你修改了模型实例的属性后,当前实例上的属性已经是新值了,NDB不会自动保留旧值的副本。所以要对比变化,必须先从数据存储中获取该实例保存前的状态。
具体实现代码
修改你的SomeModel类,添加_pre_put_hook方法即可:
class SomeModel(ndb.Model): name = ndb.StringProperty(default="") valid = ndb.BooleanProperty(default=False) def some_function(self): print("fired") # 这里要加上self,否则会被当成静态方法导致报错 def _pre_put_hook(self): # 仅对已存在的实例(有key)做旧值对比,新创建的实例无需处理 if self.key is not None: # 从数据存储拉取旧版本的实例 old_instance = self.key.get() # 确保旧实例存在,且name属性确实发生了变化 if old_instance is not None and old_instance.name != self.name: self.some_function()
验证你的示例场景
示例1(修改name):
当你从数据库取出实例,修改name为"Sam"后调用put(),_pre_put_hook会拉取旧实例(name为"John"),对比发现值不同,就会触发some_function打印"fired",完全符合预期。示例2(仅修改valid):
修改valid为True后调用put(),旧实例的name和当前实例的name都是"Sam",对比结果一致,所以不会触发函数,符合需求。
关于_post_put_hook的补充
你也可以用_post_put_hook实现同样的逻辑,但_pre_put_hook更适合这个场景:它在数据写入前触发,如果some_function执行出错,你可以通过抛出异常阻止数据保存;而_post_put_hook是在数据写入后触发,此时数据已经持久化,无法回滚。
内容的提问来源于stack exchange,提问作者Aaron
相关产品推荐
相关产品推荐

