使用 ndb.ComputedProperty 非祖先查询确保事务更新成功
Ensuring a transactional update succeeds with ndb.ComputedProperty non-ancestor query
我有一个事务函数,可以按如下方式更新模型实体
@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()
捕获异常,它 returns
(<type 'exceptions.AttributeError'>, AttributeError("'Key' object has no attribute 'reference'",), <traceback object at 0xf613c968>)
编辑 2:
如果我删除装饰器,则不会发生异常。
事实证明,ndb 有两种方便的方法来克服这个问题。有如下所示的 ndb.in_transaction
approach which returns True
if the operation is part of a transaction (so I can run or not run the lookup code). The second approach, which I've ended up using is to use the @ndb.non_transactional
装饰器,来自文档的是
Decorator to ensure that a function runs outside a transaction.
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())
我有一个事务函数,可以按如下方式更新模型实体
@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()
捕获异常,它 returns
(<type 'exceptions.AttributeError'>, AttributeError("'Key' object has no attribute 'reference'",), <traceback object at 0xf613c968>)
编辑 2: 如果我删除装饰器,则不会发生异常。
事实证明,ndb 有两种方便的方法来克服这个问题。有如下所示的 ndb.in_transaction
approach which returns True
if the operation is part of a transaction (so I can run or not run the lookup code). The second approach, which I've ended up using is to use the @ndb.non_transactional
装饰器,来自文档的是
Decorator to ensure that a function runs outside a transaction.
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())