首页 > 解决方案 > Google Cloud Platform 上的 ndb 查询间歇性地不返回任何内容

问题描述

我在 Google Cloud Platform 上部署了一个 Python 应用程序。后台有一个 Google Cloud Datastore,有两种。我使用 NDB 将数据拉入应用程序。

class AttEvent(ndb.Model):
  event = ndb.StringProperty()
  matchdate = ndb.DateTimeProperty()

class MainPage(webapp2.RequestHandler):

  def get(self):

    query = AttEvent.query().order(AttEvent.matchdate)
    for q in query.fetch():
        try:
          # application code

其中一种(上面代码中的 AtEvent)给我带来了麻烦。该应用程序将按预期部署和工作数小时/数天,但随后会间歇性地停止返回数据。调试显示 q 对象是 AttEvent 类型的合法对象,但是对于集合中的每个项目,它都显示“(对象没有字段)”。当应用程序代码尝试引用模型的属性(ieqevent)时,它会失败。

即使我不采取任何行动,查询也会在几分钟/几小时后突然重新开始工作。我看不到任何模式或明显的原因。显然,从用户的角度来看,这并不理想。

引起问题的 Kind 是静态数据,实际上只包含 3 个实体。另一种是事务性的,包含数千条记录,但从未表现出相同的行为。

故障的间歇性使我相信这与缓存有关,但我对 Python 和 GCP 还很陌生,所以我不太确定。我试过在查询之前做一个 context.clear_cache() ,但它没有效果。

我错过了一些明显的东西吗?

标签: google-app-enginegoogle-cloud-datastoregoogle-cloud-python

解决方案


我不知道为什么会这样,但我有一个可能的解决方法。由于数据是静态的并且实体看起来很小,因此您可以将它们存储在实例内存中,而不是每次需要时都查询它们。

将实体存储在模块级变量中,如下所示:

att_entities = AttEvent.query().order(AttEvent.matchdate).fetch()

class AttEvent(ndb.Model):
  event = ndb.StringProperty()
  matchdate = ndb.DateTimeProperty()

class MainPage(webapp2.RequestHandler):

  def get(self):
    for q in att_entities:
        try:
          # application code

只有在启动新实例时,您才会获得实体,只要它在您第一次完成设置时工作。作为奖励,它会使get调用更快,因为您不需要从数据存储中检索数据。

您可能需要添加额外的逻辑以att_entities根据需要进行更新。


推荐阅读