- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在尝试实现一个 ndb 模型审计,以便所有对属性的更改都存储在每个模型实例中。这是我选择实现它的 _pre_put_hook 的代码。
def _pre_put_hook(self):
# save a history record for updates
if not (self.key is None or self.key.id() is None):
old_object = self.key.get(use_cache=True)
for attr in dir(self):
if not callable(getattr(self, attr)) and not attr.startswith("_"):
if getattr(self, attr) != getattr(old_object, attr):
logging.debug('UPDATE: {0}'.format(attr))
logging.debug('OLD: {0} NEW: {1}'.format(getattr(old_object, attr), getattr(self, attr)))
问题是 old_object 总是填充了与正在更新的 self(对象)相同的值。如何在实际创建 put() 之前访问旧对象的属性值 (_pre_put)?
最佳答案
编辑:
随着时间的推移,我意识到我正在做一堆不需要完成的工作(大量 CPU/内存用于复制整个实体并在可能不需要时传递它们)。这是更新版本,它存储对原始 protobuf 的引用,并且仅在需要时反序列化它
__original = None # a shadow-copy of this object so we can see what changed... lazily inflated
_original_pb = None # the original encoded Protobuf representation of this entity
@property
def _original(self):
"""
Singleton to deserialize the protobuf into a new entity that looks like the original from database
"""
if not self.__original and self._original_pb:
self.__original = self.__class__._from_pb(self._original_pb)
return self.__original
@classmethod
def _from_pb(cls, pb, set_key=True, ent=None, key=None):
"""
save copy of original pb so we can track if anything changes between puts
"""
entity = super(ChangesetMixin, cls)._from_pb(pb, set_key=set_key, ent=ent, key=key)
if entity._original_pb is None and not entity._projection:
# _from_pb will get called if we unpickle a new object (like when passing through deferred library)
# so if we are being materialized from pb and we don't have a key, then we don't have _original
entity.__original = None
entity._original_pb = pb
return entity
当你第一次阅读实体时,复制它:
并将其放在实体本身上,以便稍后在需要时引用。这样您就不必为了进行比较而进行第二次数据存储读取
我们重写了两种不同的模型方法来实现这一点:
@classmethod
def _post_get_hook(cls, key, future):
"""
clone this entity so we can track if anything changes between puts
NOTE: this only gets called after a ndb.Key.get() ... NOT when loaded from a Query
see _from_pb override below to understand the full picture
also note: this gets called after EVERY key.get()... regardless if NDB had cached it already
so that's why we're only doing the clone() if _original is not set...
"""
entity = future.get_result()
if entity is not None and entity._original is None:
entity._original = clone(entity)
@classmethod
def _from_pb(cls, pb, set_key=True, ent=None, key=None):
"""
clone this entity so we can track if anything changes between puts
this is one way to know when an object loads from a datastore QUERY
_post_get_hook only gets called on direct Key.get()
none of the documented hooks are called after query results
SEE: https://code.google.com/p/appengine-ndb-experiment/issues/detail?id=211
"""
entity = super(BaseModel, cls)._from_pb(pb, set_key=set_key, ent=ent, key=key)
if entity.key and entity._original is None:
# _from_pb will get called if we unpickle a new object (like when passing through deferred library)
# so if we are being materialized from pb and we don't have a key, then we don't have _original
entity._original = clone(entity)
return entity
关于google-app-engine - 如何读取 _pre_put_hook 中的旧属性值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21292790/
我正在使用预放置 Hook 在每次放置之前从 api 获取一些数据。如果该 api 没有响应或处于离线状态,我希望请求失败。我是否必须围绕 put() 调用编写一个包装器,或者有什么方法可以让我们仍然
我正在尝试实现一个 ndb 模型审计,以便所有对属性的更改都存储在每个模型实例中。这是我选择实现它的 _pre_put_hook 的代码。 def _pre_put_hook(self): #
我想在模型创建时运行一些东西,而不是在模型更新时运行。我可以通过添加一个属性来做到这一点,但我想知道是否有某种内置功能专门针对创建和更新。 最佳答案 任何已存储的实体都有一个 key ,因此检查它会告
我是一名优秀的程序员,十分优秀!