使用ndb.ComputedProperty非祖先查询

时间:2018-02-23 12:10:24

标签: python-2.7 google-app-engine app-engine-ndb

我有一个事务功能,可以按如下方式更新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: 如果我删除装饰器,则不会发生异常。

1 个答案:

答案 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())