使用put创建实体时的数据存储延迟

问题描述

我正在使用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命令来解决。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...