是否可以使用NDB确定模型是否在数据存储中持久? [英] Is it possible to determine with NDB if model is persistent in the datastore or not?
问题描述
我正在从 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()
调用后都必须更新这个标志。
编辑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屋!