Сущности GAE put_multi(), использующие серверную NDB

Я использую бэкэнд для записи нескольких сущностей с помощью ndb.put_multi(list_of_entities).

Проблема, с которой я столкнулся, заключается в том, что сразу после этого, если я сделаю запрос, я не получу никаких результатов. Если я поставлю таймер сна, например, на 1 секунду, я смогу прочитать объекты, которые я только что написал.

So eg:

class Picture(ndb.Expando):
    pass

class Favourite(ndb.Expando):
    user_id = ndb.StringProperty(required=True)
    pass

#...make lists with Picture and Favourite kinds
entities = favourites
entities[1:1] = pictures
ndb.put_multi(entities)

favourites = Favourite.query().filter(Favourite.user_id == user_id).fetch(99999, keys_only=True)
logging.info(len(favourites)) #returns 0 in dev_appserver why?

Сначала предположил, что проблема связана с кэшированием. Но:

Чтение Операции сущностей NDB с несколькими ключами или сущностями:

Дополнительное примечание: эти методы корректно взаимодействуют с контекстом и кэшированием; они не соответствуют напрямую конкретным вызовам RPC.

Чтение кэширования NDB

Контекстный кэш

Контекстный кеш сохраняется только на время одного входящего HTTP-запроса и «видим» только для кода, обрабатывающего этот запрос. Это быстро; этот кеш живет в памяти. Когда функция NDB записывает в хранилище данных, она также записывает в контекстный кэш. Когда функция NDB считывает сущность, она сначала проверяет контекстный кеш. Если сущность найдена там, взаимодействия с хранилищем данных не происходит.

Запросы не ищут значения в каком-либо кеше. Однако результаты запроса записываются обратно в контекстный кэш, если так указано в политике кэширования (но не в Memcache).

Хм, я тут потерялся. Кажется, все в порядке. Даже при запросе из консоли я получаю правильную сумму, но никогда в том же обработчике, независимо от того, какая функция и т. д.

Единственное, что я заметил, это то, что когда я ставлю ожидание time.sleep(1), я получаю правильные результаты. Так что это связано с тем фактом, что ndb.put_multi может выполняться не синхронно или нет. Так запутался....


person Jimmy Kane    schedule 07.01.2013    source источник
comment
Подозреваю, что это: stackoverflow .com/questions/12367904/ возможная согласованность.   -  person Paul Collingwood    schedule 08.01.2013
comment
Да, я тоже подозревал этого @PaulC, но тогда я ошибся. Если put_multi() возвращается, не означает ли это, что объекты были помещены, а индексы и фиксация были успешными? Я не использую асинхронные методы.   -  person Jimmy Kane    schedule 08.01.2013
comment
Если вы не используете запрос предка или не получаете объекты по ключам, вы столкнетесь с возможной проблемой согласованности. Если вы используете запрос предка или ключ для получения отдельных сущностей, то, вероятно, это что-то другое.   -  person Sologoub    schedule 08.01.2013
comment
Гвидо постоянно напоминает мне, что кеш ndb кэширует только объекты, которые вы получаете по ключу/идентификатору. Запросы не кэшируются. Вы определенно сталкиваетесь с возможной проблемой согласованности, поскольку не используете транзакции.   -  person dragonx    schedule 08.01.2013
comment
И ваша фиксация прошла успешно. Это означает, что результаты в конечном итоге будут отображаться в запросе.   -  person dragonx    schedule 08.01.2013
comment
Спасибо. Я изучаю это.   -  person Jimmy Kane    schedule 08.01.2013
comment
@Sologoub Нет, я не использую запрос предков, и это решило мою проблему. Это многое объясняло. Спасибо вам всем.   -  person Jimmy Kane    schedule 08.01.2013
comment
Поэтому, если кто-то хочет опубликовать хороший ответ о запросах предков и возможной согласованности, чтобы закрыть этот вопрос, добро пожаловать.   -  person Jimmy Kane    schedule 08.01.2013
comment
это нормально для вас, чтобы ответить и принять свой собственный вопрос тоже :)   -  person Paul Collingwood    schedule 08.01.2013
comment
Хранилище данных высокой репликации Google App Engine (HRD) обеспечивает высокую доступность операций чтения и записи за счет синхронного хранения данных в нескольких центрах обработки данных. Однако задержка с момента фиксации записи до момента, когда она становится видимой во всех центрах обработки данных, означает, что запросы к нескольким группам сущностей (запросы, не относящиеся к предкам) могут гарантировать только в конечном итоге согласованные результаты. Следовательно, результаты таких запросов иногда могут не отражать недавние изменения базовых данных. Однако прямая выборка объекта по его ключу всегда непротиворечива.   -  person Jimmy Kane    schedule 09.01.2013


Ответы (1)


Ясный ум утром всегда лучше, чем головокружение ночью.

Спасибо всем за комментарии. Задача решена. Вы ведете меня по правильному пути, чтобы ответить на мой вопрос:

Я использовал запросы предков, чтобы получить правильные результаты. Стоит упомянуть следующее

Общие сведения о записи NDB: зафиксировать, сделать недействительным кэш и применить

Функция NDB, записывающая данные (например, put()), возвращает значение после аннулирования кеша; этап применения происходит асинхронно.

Это означает, что после каждого размещения фаза применения могла не завершиться.

А также:

Это поведение влияет на то, как и когда данные видны вашему приложению. Изменение может быть не полностью применено к базовому хранилищу данных примерно через несколько сотен миллисекунд после возврата из функции NDB. Запрос, не относящийся к предку, выполняемый во время применения изменения, может увидеть несогласованное состояние (т. е. часть, но не все изменение). Дополнительные сведения о времени записи и запросов см. в разделе Изоляция транзакций в App Engine.

Также некоторые сведения о согласованности операций чтения и записи взяты из Google Academy Получение данных из хранилища данных.

Хранилище данных высокой репликации Google App Engine (HRD) обеспечивает высокую доступность операций чтения и записи за счет синхронного хранения данных в нескольких центрах обработки данных. Однако задержка с момента фиксации записи до момента, когда она становится видимой во всех центрах обработки данных, означает, что запросы к нескольким группам сущностей (запросы, не относящиеся к предкам) могут гарантировать только в конечном итоге согласованные результаты. Следовательно, результаты таких запросов иногда могут не отражать недавние изменения базовых данных. Однако прямой выбор объекта по его ключу всегда согласован.

Спасибо @Paul C за постоянную помощь и @dragonx и @sologub за помощь в понимании.

person Jimmy Kane    schedule 08.01.2013