5

我正在使用后端编写多个实体ndb.put_multi(list_of_entities)

我遇到的问题是,在那之后,如果我进行查询,那么我没有得到任何结果。如果我设置一个睡眠定时器,例如 1 秒,我可以读取我刚刚编写的实体。

所以例如:

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 函数读取实体时,它首先检查上下文缓存。如果在此处找到实体,则不会发生 Datastore 交互。

查询不会在任何缓存中查找值。但是,如果缓存策略如此,查询结果将被写回上下文缓存(但永远不会写回 Memcache)。

嗯,我在这里迷路了。一切似乎都很好。即使从控制台查询我得到正确的总和,但永远不会在同一个处理程序上,无论什么功能等。

我唯一注意到的是,当等待时time.sleep(1),我得到了正确的结果。ndb.put_multi所以这与可能不会同步完成的事实有关。如此迷茫....

4

1 回答 1

5

早上头脑清醒总比晚上头脑昏沉好。

谢谢大家的意见。问题解决了。您以正确的方式引导我,以便回答我的问题:

我使用祖先查询来正确获得结果。值得一提的是以下几点

了解 NDB 写入:提交、使缓存无效和应用

写入数据的 NDB 函数(例如 put())在缓存失效后返回;Apply 阶段异步发生。

这意味着在每次放置之后,应用阶段可能还没有完成。

和:

此行为会影响数据对您的应用程序可见的方式和时间。在 NDB 函数返回后几百毫秒左右,更改可能不会完全应用于基础数据存储区。在应用更改时执行的非祖先查询可能会看到不一致的状态(即,部分但不是全部更改)。有关写入和查询时间的更多信息,请参阅 App Engine 中的事务隔离。

还有一些关于读取和写入一致性的事情,取自Google Academy 从数据存储区检索数据

Google App Engine 的 High Replication Datastore (HRD) 通过在多个数据中心同步存储数据,为您的读写提供高可用性。但是,从提交写入到它在所有数据中心中可见的延迟意味着跨多个实体组的查询(非祖先查询)只能保证最终一致的结果。因此,此类查询的结果有时可能无法反映基础数据的最新更改。但是,通过其键直接获取实体始终是一致的

感谢@Paul C 的不断帮助,感谢@dragonx 和@sologoub 帮助我理解。

于 2013-01-08T13:02:56.060 回答