我有一个事务功能,可以按如下方式更新Model实体
@ndb.transactional(xg=True)
def do_something(some_key):
some_entity = some_key.get()
some_entity.some_property = "New value"
some_entity.put()
class TheModel(ndb.Model):
some_property = ndb.StringProperty()
blob_key = ndb.BlobKeyProperty()
@ndb.ComputedProperty
def md5(self):
try:
bi = blobstore.BlobInfo(self.blob_key)
if bi:
return bi.md5_hash
return None
except:
logging.error(sys.exc_info())
当我运行do_something
时,put失败了 - 从测试中我可以看出这是由于函数的事务性质。我收集blobstore查询/按键获取导致失败。
是否有一种确定的方法可以确保ComputedProperties(计算涉及非祖先查询)与事务函数中包含的模型一起工作?
编辑1:
我正在使用sys.exc_info()
捕获异常并返回
(<type 'exceptions.AttributeError'>, AttributeError("'Key' object has no attribute 'reference'",), <traceback object at 0xf613c968>)
编辑2: 如果我删除装饰器,则不会发生异常。
答案 0 :(得分:1)
事实证明,ndb有两种方便的方法可以解决这个问题。如果操作是事务的一部分,则ndb.in_transaction
方法返回True
(因此我可以运行或不运行查找代码)。我最终使用的第二种方法是使用@ndb.non_transactional
装饰器,如下所示,来自文档的是
装饰器,以确保函数在事务外运行。
class TheModel(ndb.Model):
some_property = ndb.StringProperty()
blob_key = ndb.BlobKeyProperty()
@ndb.ComputedProperty
@ndb.non_transactional
def md5(self):
try:
bi = blobstore.BlobInfo(self.blob_key)
if bi:
return bi.md5_hash
return None
except:
logging.error(sys.exc_info())