#python #google-app-engine #google-cloud-datastore #app-engine-ndb
#python #google-app-engine #google-cloud-хранилище данных #app-engine-ndb
Вопрос:
Я разрабатываю приложение, используя эмулятор облачного хранилища данных (2.1.0) и библиотеку Python google-cloud-ndb (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)
это приведет к сбою itermittently, потому get()
что метод возвращает None
.
Это происходит только примерно при 1 из 10 вызовов.
Чтобы продемонстрировать, я создал этот скрипт (также доступный с готовой к запуску настройкой docker-compose на GitHub):
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()
вызова?
Обновление Я могу подтвердить, что это проблема только с эмулятором хранилища данных. При тестировании на app Engine и Firestore в режиме хранилища данных объекты доступны сразу после вызова put()
.
Комментарии:
1. Происходит ли это, если вы извлекаете объект через его
id
илиkey
? НапримерSimpleMOdel.get_by_id(<some-id>)
, илиentity.key().get()
(проверьте синтаксис, я некоторое время не использовал хранилище данных)2. @snakecharmerb только что протестирован, и нет, проблема не возникает при использовании
SampleModel.get_by_id(int_id)
… Это заставляет меня думать, что проблема заключается в задержке индексации. Интересно, есть ли способ принудительно выполнить индексацию?3. Возможно, он пытается имитировать возможную согласованность?
4. @snakecharmerb только что просмотрел это, и есть флаг
--consistency
, который можно установить1.0
, чтобы отключить это… Однако проблема все еще сохраняется.5. Исправление: я неправильно применил изменение…
--consistency=1.0
устраняет проблему.
Ответ №1:
Оказалось, что проблема связана с эмулятором, пытающимся воспроизвести конечную согласованность.
В отличие от реляционных баз данных, хранилище данных не гарантирует, что данные будут доступны сразу после их публикации. Это связано с тем, что часто возникают задержки репликации и индексации.
Для таких вещей, как модульные тесты, это можно решить, перейдя --consistency=1.0
к datastore start
команде, как описано здесь .