GAE python NDB投影查询可在开发中使用,但不能在生产中使用

时间:2018-12-05 00:32:28

标签: python google-app-engine google-cloud-datastore projection app-engine-ndb

我一直在碰壁,因为我的Google App Engine python项目有一个非常简单的NDB投影查询,该查询在我的本地计算机上可以正常工作,但是在部署到生产环境时却神秘地失败了。

增加了一个谜底……作为测试,我在另一个属性上添加了一个相同的投影,它在开发和生产中都可以使用!有人可以帮忙吗?这里是更多详细信息:

我有以下代表费用的实体:

class Entry(ndb.Model):
    datetime = ndb.DateTimeProperty(indexed=True, required=True)
    amount = ndb.IntegerProperty(indexed=False, required=True)
    payee = ndb.StringProperty(indexed=True, required=True) 
    comment = ndb.StringProperty(indexed=False)
    # ...

稍后在代码中,我正在对Entry.payee进行投影(以获取所有收款人的列表)。作为测试,我还对Entry.datetime添加了一个投影:

log_msg = '' # For passing debug info to the browser

payeeObjects = Entry.query(ancestor=exp_traq_key(exp_traq_name), projection=[Entry.payee]).fetch()
payees = []
for obj in payeeObjects:
    payees.append(obj.payee)
log_msg += '%d payees: %s' % (len(payees), str(payees))

log_msg += ' ------------------- ' # a visual separator

dtObjects = Entry.query(ancestor=exp_traq_key(exp_traq_name), projection=[Entry.datetime]).fetch()
dts = []
for obj in dtObjects:
    dts.append(obj.datetime)
log_msg += '%d datetimes: %s' % (len(dts), str(dts))

#...other code, including passing log_msg down to the client

以下是开发人员环境中的输出(注意,控制台中显示了收款人列表和日期时间列表):

enter image description here

这是部署到应用程序引擎时的输出。我无法返回收款人清单。即使在dev中,它仍然可以很好地返回列表:

enter image description here

我确保在GAE上正确设置了索引:

enter image description here

请帮助!


2018-12-05更新: 我在生产中添加了更多条目,他们被选中了!查看截图。但是较旧的条目仍未返回。 enter image description here

我的直接反应是,需要以某种方式“刷新”数据存储区索引,以便它可以“查看”旧条目。但是事情是我昨天删除并重新创建了索引,这意味着它应该有旧条目...因此仍然需要帮助来解决这个难题!

1 个答案:

答案 0 :(得分:3)

我知道了。天哪,这根本不是直观的。我希望GAE文档在这一点上能更好...

我在生产中的数据存储区包含许多以前创建的条目。作为我尝试对Entry.payee进行投影的最新代码的一部分,我不得不将Entry.payee的定义从未索引更改为索引,如下所示:

payee = ndb.StringProperty(indexed=True, required=True) # Originally was indexed=False

因此,现在投影查询将忽略所有位于数据存储区中的条目,因为收款人上的索引会忽略这些条目。

所以我现在要做的是以某种方式将所有这些旧实体迁移为 indexed = True


更新-这是我进行此迁移的方式。结果比预期的要简单。

def runPayeeTypeMigration(exp_traq_name):
  Entry.query(ancestor=exp_traq_key(exp_traq_name)).fetch()
  for entry in entries:
    entry.put()

这是通过将所有条目读入更新的数据结构(Entry.payee被索引= True的那个)并将其写回到数据存储中来进行的,因此该实体现在将被索引。