Скорее всего, это Eventual Consistency. При проектировании системы с помощью Cloud Datastore необходимо предусмотреть случай, когда для обновления этих запросов может потребоваться время. Скорее всего, повторное развертывание вашего приложения в этом случае займет достаточно времени, чтобы информация обновилась к тому времени, когда вы снова проверите.
Чтобы гарантировать строгую согласованность, вы захотите организовать свои данные в группы сущностей. Важным соображением для вашей модели данных является то, что внутри EG вы можете запрашивать строго согласованным образом. Однако вы можете обновлять только одну группу сущностей с постоянной скоростью 1 обновление в секунду (хотя это обновление может быть пакетным).
Попытайтесь выровнять эти группы сущностей по естественным границам, чтобы ограничить скорость записи в любую данную группу сущностей по мере масштабирования вашего приложения. Например, у вас может быть одна группа сущностей для каждого пользователя или, в случае вашего приложения, одна группа сущностей для каждого Shop
. Если вы поместите все Product
для одного Shop
в одну группу сущностей, вы всегда сможете перечислить все Product
в магазине строго согласованным образом. Вы не сможете увеличить количество людей, добавляющих товары в магазин (вы можете записывать продукты в магазин до одной партии в секунду), но это, вероятно, будет приемлемым ограничением для системы.
Поэтому вместо этого рассмотрим следующий макет:
class Product(ndb.Model):
name = ndb.StringProperty()
description = ndb.StringProperty()
code = ndb.StringProperty()
class Category(ndb.Model):
name = ndb.StringProperty()
class Shop(ndb.Model):
name = ndb.StringProperty()
category = ndb.StructuredProperty(Category)
address = ndb.StringProperty()
class ProductInShop(ndb.Model):
product = ndb.StructuredProperty(Product)
price = ndb.FloatProperty()
Когда вы создаете ProductInShop
, вы хотите установить родителя на ключ Shop
, частью которого он является. Например:
ProductInShop(parent=ndb.Key(Shop, request.shop_key),
product=Product(...), price=10.0).put()
Затем вы можете выполнить запрос для одного продукта в данном магазине с определенным кодом:
product_in_shop = ndb.gql(
'SELECT * FROM ProductInShop WHERE \
product.code = :1 AND ANCESTOR IS :2 LIMIT 1',
request.code,
ndb.Key(Shop, request.shop_key)
).get()
В качестве примечания: если ваш code
уникален для одного продукта, рассмотрите возможность установки идентификатора ProductInShop
в качестве кода. Тогда вам не нужно выдавать запрос для этого:
ProductInShop(id=product.code, product=product, price=10.0).put()
Затем вы можете найти свой ProductInShop
без запроса с помощью:
product_in_shop = ndb.Key(Shop, request.shop_key, ProductInShop, request.code).get()
person
Patrick Costello
schedule
05.05.2016