10

我想知道是否有人在 Google App Engine 的 NDB 上遇到过奇怪的问题:在创建一个新实体并将其保存后put();然后query()立即,总是少一件。例如,

class Item(ndb.Model):
    ...
    ...

items = Item.query().fetch()
length1 = len(items)
item = Item()
item.put()
items = Item.query().fetch()
length2 = len(items)

在上面,length1总是等于length2。但是,length2稍后重新访问相同的 HTML 页面时会更正。问题是什么?谢谢。

4

5 回答 5

21

这是预期的行为;您上面的查询只是最终一致的。也就是说,您不能保证在查询时获得最新的结果。

您可以通过使用祖先查询来解决这个问题(请参阅上面的链接)。对于您的示例,您需要为每个项目提供一个父实体,然后使用Item.query().ancestor(theParentEntity).fetch().

于 2013-03-17T13:13:34.770 回答
8

正如@JesseRusak 所说,你需要一个虚拟祖先来解决这个小问题(我最近遇到了和你一样的问题)。

但我没有制作新的 DummyEntity,只是为 DummyAncestor 制作了一个 DummyKey。试试这个解决你的问题:

class Item(ndb.Model): ... ... items = Item.query(ancestor=ndb.Key(Item, 'Items')).fetch() length1 = len(items) item = Item(parent=ndb.Key(Item, 'Items')) item.put() items = Item.query(ancestor=ndb.Key(Item, 'Items')).fetch() length2 = len(items)

至少在我的情况下,DummyAncestor 起作用了。

于 2013-05-21T11:38:21.103 回答
1

你可以在这里参考他们关于 nbd 的教程。
他们使用一个函数根据他们的 ndb 模型的一些属性生成一个祖先键。根据您想要数据库的方式,您可以在每个用户都有多个帖子的数据库中使用对多个项目唯一的属性,例如用户属性。或者您可以添加一个新的虚拟属性,例如dummy = ndb.StringProperty()并为每个项目使用相同的字符串初始化该虚拟属性,这样您将获得以后可以过滤的所有条目。

于 2013-07-25T20:14:37.603 回答
1

您遇到的问题是 ndb 提供“最终一致”的数据。对于最终一致的数据,ndb 通常需要几秒钟来更新数据,以便您以后可以使用它。这适用于大多数应用程序,但如果您在提交新实体后立即需要数据,则需要“强一致性”数据。

谷歌在这篇很棒的文章中解释了不同之处: https ://cloud.google.com/appengine/docs/python/datastore/structuring_for_strong_consistency

于 2015-05-01T15:07:30.783 回答
-3

我通过进行适当的查询、创建新的模型记录、然后在返回之前将其附加到我的查询来解决这个问题。修改你的,它看起来像:

class Item(ndb.Model):
    ...
    ...

items = Item.query().fetch()
length1 = len(items)
item = Item()
item.put()

appended_items = list()
for existing_item in items:
    appended_items.append(existing_item)

appended_items.append(item)
length2 = len(appendeditems)

在这种情况下, appended_items 包含您的查询以及新元素。列表生成效率低下,但我是 python/ndb 菜鸟,可能有一种方法可以将 Collection 直接从 Query 模型中取出,这样会好得多。

于 2013-11-17T20:32:28.743 回答