我对ndb.Model
类的这些辅助方法有所了解:
@classmethod
@ndb.transactional(retries=2)
def new(cls, *args, **kwargs):
internal_name = kwargs['internal_name']
new_company = cls.get_or_insert(internal_name, **kwargs)
new_company.put()
return new_company
@classmethod
@ndb.transactional(retries=2)
def get(cls, internal_name):
result = cls.query(cls.internal_name == internal_name)
if result.count() != 1:
raise Exception("this is a problem");
return result.get()
我写了一个测试来验证我的假设:
def testCanCreateRetrieveCompany(self):
company = self.models.Company.new(internal_name="google", description="search engine")
reread_company = self.models.RichCompany.get("internal_name")
self.assertTrue(True)
但是,这次失败并且每次都有this is a problem
例外!
但是,如果我将测试更改为:
def testCanCreateRetrieveCompany(self):
company = self.models.Company.new(internal_name="google", description="search engine")
company.put()
reread_company = self.models.RichCompany.get("internal_name")
self.assertTrue(True)
这似乎过去了。我绝对不知道为什么当第一个没有时它会通过。此外,删除@ndb.transactional
运算符似乎使这项工作。除了我显然希望这是交易性的。
不确定发生了什么。我知道在关于事务读取的文档中有一些警告(只看到事务的原始读取状态),但我不知道有任何这样的写入警告。有没有人有任何见解?
答案 0 :(得分:1)
因此,经过一番挖掘,我认为我只是看到darn更新可能是事务性的,但实际上仍然是最终的一致 - 也就是说,仅仅因为该方法是事务性的,并不意味着更新制作将是非常一致的。我最终在公司密钥中添加了父/祖先组件(因此所有公司对象共享一个祖先),这给了我想要的效果。参见:
ndb and consistency: Why is happening this behavior in a query without a parent