问题:数据存储更新速度太慢 - 在提交创建实体的表单后,需要在显示数据存储区中的实体的结果页面上点击重新加载。
预期行为:实体应该出现在查询中,因为我正在使用NDB来自动缓存数据存储。
问题重播步骤
预期行为的说明
由于NDB自动使用内存缓存,因此不应执行步骤4和步骤5。单击表单上的“提交”后,您输入的数字应该会显示出来。我也使用常规的appengine DB观察了这种行为,我知道我可以用memcache解决它。
以下是一些代码,您可以使用AppEngineLauncher创建的默认main.py来复制此问题:
import webapp2
from google.appengine.ext import ndb
class SmallModel(ndb.Model):
n = ndb.IntegerProperty(required=True)
stamp = ndb.DateTimeProperty(auto_now_add=True)
class MainHandler(webapp2.RequestHandler):
def get(self):
self.response.write('Hello world. Simple form. <form method="post"><input name="n" type="number"><input type="submit"></form>')
def post(self):
entity = SmallModel(n=int(self.request.get('n')))
entity.put()
self.redirect('/list')
class List(webapp2.RequestHandler):
def get(self):
self.response.out.write("here's a list of entities:")
entities = SmallModel.query()
for entity in entities.iter():
self.response.out.write(" %s " % entity.n)
self.response.out.write("...end list.")
app = webapp2.WSGIApplication([
('/', MainHandler),
('/list',List)
], debug=True)
任何帮助/建议?先感谢您!我已经能够在我测试的两个浏览器中重现这个问题 - Chrome和Safari。
答案 0 :(得分:3)
我设法得到了我预期的行为,我的更新代码如下。我从具有我期望的行为的“留言板”示例代码中提取了一个提示,并设置了父键。我还深入研究了NDB文档。设置父键可以实现我期望的一致性,但限制写入每秒一次(我假设这意味着给定父键的所有子项,而不是给定模型的所有实体)。
这是我改变以消除步骤4和5.我只是在新实体上设置父键,并使用此父键执行祖先查询。 (当然,这是用于说明一点的超级最小代码,我对创建数字列表的模型没有真正的兴趣。;))
import webapp2
from google.appengine.ext import ndb
def parent_key():
return ndb.Key('My','Entities')
class SmallModel(ndb.Model):
n = ndb.IntegerProperty(required=True)
stamp = ndb.DateTimeProperty(auto_now_add=True)
class MainHandler(webapp2.RequestHandler):
def get(self):
self.response.write('Hello world. Simple form. <form method="post"><input name="n" type="number"><input type="submit"></form>')
def post(self):
entity = SmallModel(parent=parent_key(),n=int(self.request.get('n')))
entity.put()
self.redirect('/list')
class List(webapp2.RequestHandler):
def get(self):
self.response.out.write("here's a list:")
entities = SmallModel.query(ancestor=parent_key())
for entity in entities.iter():
self.response.out.write(" %s " % entity.n)
self.response.out.write("...end list.")
app = webapp2.WSGIApplication([
('/', MainHandler),
('/list',List)
], debug=True)
感谢阅读和参与。
答案 1 :(得分:2)
这是最终一致性的行为。我不确定你要做什么,也许你可以改变你的数据建模,所以fetch总是非常一致。
在您的数字列表示例中,您可以将它们存储在一个实体的ListProperty中,这样您就可以始终以强一致的方式获取它
答案 2 :(得分:1)
ndb非常明确,它不会在memcache中查找查询结果。只有get()从memcache中获取实体。
特别是文档说 -
查询不会在任何缓存中查找值。但是,查询结果 如果缓存策略这样说,则写回到上下文缓存中 (但永远不要Memcache)。
https://developers.google.com/appengine/docs/python/ndb/cache无文字缓存部分。
另见这个关于同一个ndb和memcache的问题,How automatic NDB caching works?
您可能会在生产中发现同样的问题。这是因为最终在开发环境中模拟了最终的一致性。您需要使用get来确保一致性或处理查询结果的潜在延迟。
答案 3 :(得分:1)
我遇到了类似的问题。谢谢你的解决方案。 顺便说一下,我认为GAE文档已经从原来的解决方案中改变了。
对于这一行:
entities = SmallModel.query(ancestor=parent_key())
应该是:
entities = SmallModel.ancestor(parent_key())