Google应用引擎ndb: put()然后query(),总是少一个项目



我想知道是否有人在谷歌应用引擎的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页面时被纠正。有什么问题吗?谢谢。

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

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

正如@JesseRusak所说,您需要一个Dummy祖先来解决这个小问题(我最近遇到了与您相同的问题)。

但是我没有创建一个新的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工作了。

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

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

谷歌在这篇伟大的文章中解释了两者的区别:https://cloud.google.com/appengine/docs/python/datastore/structuring_for_strong_consistency

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

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新手,可能有一种方法可以从查询模型中获得集合,这将会好得多。

最新更新