问题描述
我正在使用Cloud Datastore Emulator(2.1.0)和google-cloud-ndb Python库(1.6)开发应用程序。
我发现通过查询可检索的实体存在间歇性延迟。
例如,如果我创建这样的实体:
my_entity = MyEntity(foo='bar')
my_entity.put()
get_my_entity = MyEntity.query().filter(MyEntity.foo == 'bar').get()
print(get_my_entity.foo)
由于get()
方法返回None
,它会间歇性地失败。
这仅发生在十分之一的通话中。
为了演示,我创建了此脚本(也可用于在GitHub上运行docker-compose安装程序):
import random
from google.cloud import ndb
from google.auth.credentials import AnonymousCredentials
client = ndb.Client(
credentials=AnonymousCredentials(),project='local-dev',)
class SampleModel(ndb.Model):
"""Sample model."""
some_val = ndb.Stringproperty()
for x in range(1,1000):
print(f'Attempt {x}')
with client.context():
random_text = str(random.randint(0,9999999999))
new_model = SampleModel(some_val=random_text)
new_model.put()
retrieved_model = SampleModel.query().filter(
SampleModel.some_val == random_text
).get()
print(f'Model Text: {retrieved_model.some_val}')
避免这种间歇性故障的正确方法是什么?有没有办法确保在put()
调用之后实体始终可用?
更新
我可以确认这只是数据存储模拟器的问题。在应用引擎和数据存储区模式下的Firestore上进行测试时,调用put()
后立即可以使用实体。
解决方法
事实证明,该问题与模拟器试图复制最终的一致性有关。
与关系数据库不同,数据存储区不保证数据发布后立即可用。这是因为通常存在复制和索引延迟。
对于单元测试之类的问题,可以通过将--consistency=1.0
传递给here记录的datastore start
命令来解决。