Google App Engine ndb简单查询给出NeedIndexError

时间:2019-06-28 04:26:22

标签: indexing google-cloud-firestore google-cloud-datastore app-engine-ndb google-app-engine-python

我有一个使用python 2.7和Cloud Datastore的Google App Engine项目(它可能是Cloud Firestore,但稍后会介绍更多内容)。我的问题是当我进行简单查询时Data.query(ndb.AND(Data.timeStamp >= day, Data.timeStamp < day + datetime.timedelta(days=1))).order(Data.timeStamp)我得到500(服务器错误),并且该错误在日志中显示:

NeedIndexError:找不到匹配的索引。
此查询的建议索引为:
-种类:数据
  属性:
  -名称:timeStamp


该建议的索引是一个简单查询的索引。如果我将该查询添加到index.yaml文件并运行gcloud datastore indexes create index.yaml,则会收到以下消息:

错误:(gcloud.datastore.indexes.create)服务器用代码[400]响应:
  错误的请求意外HTTP状态为400。
  为entity_type创建复合索引失败:“数据”
财产{
  名称:“ timeStamp”
  方向:升序
}
祖先:假
:此索引: IndexDef {semantics = DATASTORE,kind = Data,indexAncestor = NONE,propertyDefs = [PropertyDef {path = timeStamp,mode = ORDERED,direction = ASCENDING}]}
不需要,因为内置了单属性索引。


因此,由于需要索引,所以无法运行此查询,但不允许创建索引。所以我的问题是,如何运行此查询?

更多信息:
不确定,但这可能是相关的:当我进入Google Cloud Console(console.cloud.google.com)并单击“数据存储”标签时,它声称我使用“纯模式下的Cloud Firestore”,并为我提供了指向Firestore标签。当我去那里时,我可以在Firestore中看到我的所有数据。即使我使用python2和ndb api来访问Cloud Datastore / Firestore,所有这一切都会发生。
另外,当我单击“ Firestore”选项卡中的索引页面时,GCP声称我的所有字段都已为简单查询建立索引。
最后,dev_appserver.py没有在index.yaml文件中为我生成索引(如预期的那样)。

这是我的代码:
main.py

import datetime
from google.appengine.ext import ndb

class Data(ndb.Model):
    timeStamp = ndb.DateTimeProperty(indexed=True)


#WSGI compatible function
def app(env, startResponse):

    headers = [('Content-type', 'text/plain')]
    status = "200 OK"

    path = env["PATH_INFO"]

    if path == "/doData":

        Data(timeStamp = datetime.datetime.now()).put()

        startResponse(status, headers)
        return ["done"]


    elif path == "/getData":

        day = datetime.datetime.strptime("2019-06-28", "%Y-%m-%d")

        records = Data.query(ndb.AND(Data.timeStamp >= day, Data.timeStamp < day + datetime.timedelta(days=1))).order(Data.timeStamp).fetch(10)
        print(records)

        startResponse(status, headers)
        return [str(record.timeStamp) + "\n" for record in records]


    startResponse("404 NOT FOUND", headers)
    return ["404 Page Not Found"]


app.yaml:

runtime: python27
api_version: 1
threadsafe: yes

handlers:
- url: /.*
  script: main.app


index.yaml:

indexes:

- kind: Data
  properties:
  - name: timeStamp

# AUTOGENERATED

# This index.yaml is automatically updated whenever the dev_appserver
# detects that a new type of query is run.  If you want to manage the
# index.yaml file manually, remove the above marker line (the line
# saying "# AUTOGENERATED").  If you want to manage some indexes
# manually, move them above the marker line.  The index.yaml file is
# automatically uploaded to the admin console when you next deploy
# your application using appcfg.py.


预先感谢!

1 个答案:

答案 0 :(得分:1)

额外的信息确实是相关的。您的项目在纯模式下使用Cloud Firestore,而不在数据存储模式下使用Cloud Firestore:

When I go into the Google Cloud Console and click on the Datastore tab it claims that I use "Cloud Firestore in Native mode" and gives me a link to the Firestore tab.

如果要使用NDB和Cloud Datastore API,则需要创建一个新项目,并在create your database时选择Data Store模式下的Cloud Firestore。

如果继续使用此项目,则应改用Cloud Firestore client libraries之一。