是否可以使用NDB确定模型是否在数据存储中持久? [英] Is it possible to determine with NDB if model is persistent in the datastore or not?

查看:112
本文介绍了是否可以使用NDB确定模型是否在数据存储中持久?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在从 db.Model 迁移到 ndb.Model 。在完成此迁移之前,我必须解决的唯一问题是没有 Model.is_saved 方法。我在我的应用程序中使用了 db.Model.is_saved 来确定是否必须更新分片计数器 put / delete ,检查创建实体时是否有冲突的键。



文档说明 ndb。模型对于 is_saved 方法没有等价物。我可以使用 get_or_insert 而不是 is_saved 来重新实现一些用例。但不是全部。



对于我创建的每个实例,我都可以为标记设置 _in_memory_instance 通过调用构造函数。但它不能解决我的问题。我至少在每一次 put()调用后都必须更新这个标志。

现在的问题是:编辑1:忘记提及:所有实体都有密钥,因此请检查<$>是否有更好的方法来确定模型是否在数据存储中持久存在? c $ c> Model._has_complete_key()不适用于我。



编辑2:讨论之后 https://groups.google.com/d/topic/google-appengine/Tm8NDWIvc70/discussion 它似乎是解决我的问题的唯一方法是使用 _post_get_hook / _post_put_hook 。我想知道为什么这样一个微不足道的东西没有被包含在官方的API中。



编辑3:我结束了所有模型的下一个基类。现在我可以保持我的代码库(几乎)不变:

  class BaseModel(ndb.Model):

@classmethod
def _post_get_hook(cls,key,future):
self = future.get_result()
如果self:
self._is_saved = bool(key)

def _post_put_hook(self,future):
self._is_saved = future.state == future.FINISHING

def is_saved(self):
if self。 _has_complete_key():
return getattr(self,_is_saved,False)
return False


解决方案

要在NDB中获得相同的状态,您需要
post-get-hook和post-put-hook的组合来设置标志。例如:
$ b

  class Employee(ndb.Model):
< properties here>

saved = False#类变量提供默认值

@classmethod
def _post_get_hook(cls,key,future):
obj = future.get_result ()
如果obj不是无:
#测试需要,因为即使get()失败也会调用post_get_hook!
obj.saved = True

def _post_put_hook(self,future):
self.saved = True

没有必要检查未来的状态 - 当调用
钩子时,未来总是有结果。这是因为
挂钩实际上是对未来的回调。但是,需要
检查它的结果是否为!



PS:在事务内部,一旦put()调用就会调用钩子回报;交易成功或失败不会影响他们。请参阅 https://developers.google.com/appengine/docs/python/ndb/contextclass#Context_call_on_commit ,以便在成功提交后运行一个钩子。


I am in process of migration from db.Model to ndb.Model. The only issue that I have to solve before finish this migration is that there is no Model.is_saved method. I have used db.Model.is_saved in my application to determine if sharded counters must be updated on put/delete, to check for conflicted keys on creating entities etc.

The documentation says that ndb.Model has no equivalent for is_saved method. I can reimplement some use cases with get_or_insert instead of is_saved. But not all of them.

As a dirty hack I can set flag like _in_memory_instance for every instance I have created by calling constructor. But it does not solve my issue. I still have to update this flag at least after every put() call.

The question is: is there better way to determine if model is persistent in the datastore or not without extra datastore hit?

Edit 1: Forgot to mention: all the entities got keys so check for Model._has_complete_key() does not work for me.

Edit 2: After this discussion https://groups.google.com/d/topic/google-appengine/Tm8NDWIvc70/discussion it seems to be the only way to solve my issue is to use _post_get_hook/_post_put_hook. I wondering why such a trivial thing was not included in official API.

Edit 3: I ended up with next base class for all my models. Now I can leave my codebase (almost) untouched:

class BaseModel(ndb.Model):

    @classmethod
    def _post_get_hook(cls, key, future):
        self = future.get_result()
        if self:
            self._is_saved = bool(key)

    def _post_put_hook(self, future):
        self._is_saved = future.state == future.FINISHING

    def is_saved(self):
        if self._has_complete_key():
            return getattr(self, "_is_saved", False)
        return False

解决方案

To get the same kind of state in NDB you would need a combination of post-get-hook and post-put-hook to set a flag. Here's a working example:

class Employee(ndb.Model):
  <properties here>

  saved = False  # class variable provides default value

  @classmethod
  def _post_get_hook(cls, key, future):
    obj = future.get_result()
    if obj is not None:
      # test needed because post_get_hook is called even if get() fails!
      obj.saved = True

  def _post_put_hook(self, future):
    self.saved = True

There's no need to check for the status of the future -- when either hook is called, the future always has a result. This is because the hook is actually a callback on the future. However there is a need to check if its result is None!

PS: Inside a transaction, the hooks get called as soon as the put() call returns; success or failure of the transaction doesn't enter affect them. See https://developers.google.com/appengine/docs/python/ndb/contextclass#Context_call_on_commit for a way to run a hook after a successful commit.

这篇关于是否可以使用NDB确定模型是否在数据存储中持久?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆