我正在尝试使用python API在Google Datastore中运行查询(描述为here)。数据存储区中我的数据模型是我有一定的Location
s,包含名称,纬度和经度,然后是WeatherData
个包含温度等天气数据和时间戳的对象。每个WeatherData
都有一个与之相关的父Location
实体。我想在特定时间范围内查询给定WeatherData
的所有Location
s。但是,当我尝试运行祖先查询时,我相信它也会将过滤器应用于祖先,这不会起作用,因为Location
具有与WeatherData
不同的字段。请参阅下面的代码:
from google.cloud import datastore
from datetime import datetime
client = datastore.Client()
dad = client.key('Location','Boston')
query = client.query(kind='WeatherData', ancestor=dad)
start_date = datetime(2018, 1, 20, 0, 0)
end_date = datetime(2018, 1, 21, 0, 0)
query.add_filter('time', '>', start_date)
query.add_filter('time', '<', end_date)
query_iter = query.fetch()
temps = [entity.get('apparentTemperature') for entity in query_iter]
我只能查询祖先,我也可以查询没有祖先,但使用时间过滤器。我也尝试运行祖先查询,只是按时间排序,而不是过滤它,但它不起作用。当我运行上面的代码时,它会产生错误:
Traceback (most recent call last):
File "/Users/andyw/frontend_data/venv/lib/python3.6/site-packages/google/gax/retry.py", line 121, in inner
return to_call(*args)
File "/Users/andyw/frontend_data/venv/lib/python3.6/site-packages/google/gax/retry.py", line 68, in inner
return a_func(*updated_args, **kwargs)
File "/Users/andyw/frontend_data/venv/lib/python3.6/site-packages/grpc/_channel.py", line 484, in __call__
return _end_unary_response_blocking(state, call, False, deadline)
File "/Users/andyw/frontend_data/venv/lib/python3.6/site-packages/grpc/_channel.py", line 434, in _end_unary_response_blocking
raise _Rendezvous(state, None, None, deadline)
grpc._channel._Rendezvous: <_Rendezvous of RPC that terminated with (StatusCode.FAILED_PRECONDITION, no matching index found. recommended index is:
- kind: WeatherData
ancestor: yes
properties:
- name: time
)>
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/Users/andyw/frontend_data/venv/lib/python3.6/site-packages/google/cloud/datastore/_gax.py", line 74, in _catch_remap_gax_error
yield
File "/Users/andyw/frontend_data/venv/lib/python3.6/site-packages/google/cloud/datastore/_gax.py", line 134, in run_query
return super(GAPICDatastoreAPI, self).run_query(*args, **kwargs)
File "/Users/andyw/frontend_data/venv/lib/python3.6/site-packages/google/cloud/gapic/datastore/v1/datastore_client.py", line 258, in run_query
return self._run_query(request, options)
File "/Users/andyw/frontend_data/venv/lib/python3.6/site-packages/google/gax/api_callable.py", line 452, in inner
return api_caller(api_call, this_settings, request)
File "/Users/andyw/frontend_data/venv/lib/python3.6/site-packages/google/gax/api_callable.py", line 438, in base_caller
return api_call(*args)
File "/Users/andyw/frontend_data/venv/lib/python3.6/site-packages/google/gax/api_callable.py", line 376, in inner
return a_func(*args, **kwargs)
File "/Users/andyw/frontend_data/venv/lib/python3.6/site-packages/google/gax/retry.py", line 127, in inner
' classified as transient', exception)
google.gax.errors.RetryError: RetryError(Exception occurred in retry method that was not classified as transient, caused by <_Rendezvous of RPC that terminated with (StatusCode.FAILED_PRECONDITION, no matching index found. recommended index is:
- kind: WeatherData
ancestor: yes
properties:
- name: time
)>)
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 1, in <listcomp>
File "/Users/andyw/frontend_data/venv/lib/python3.6/site-packages/google/api_core/page_iterator.py", line 186, in _items_iter
for page in self._page_iter(increment=False):
File "/Users/andyw/frontend_data/venv/lib/python3.6/site-packages/google/api_core/page_iterator.py", line 217, in _page_iter
page = self._next_page()
File "/Users/andyw/frontend_data/venv/lib/python3.6/site-packages/google/cloud/datastore/query.py", line 498, in _next_page
query=query_pb,
File "/Users/andyw/frontend_data/venv/lib/python3.6/site-packages/google/cloud/datastore/_gax.py", line 134, in run_query
return super(GAPICDatastoreAPI, self).run_query(*args, **kwargs)
File "/usr/local/Cellar/python3/3.6.3/Frameworks/Python.framework/Versions/3.6/lib/python3.6/contextlib.py", line 99, in __exit__
self.gen.throw(type, value, traceback)
File "/Users/andyw/frontend_data/venv/lib/python3.6/site-packages/google/cloud/datastore/_gax.py", line 82, in _catch_remap_gax_error
six.reraise(error_class, new_exc, sys.exc_info()[2])
File "/Users/andyw/frontend_data/venv/lib/python3.6/site-packages/six.py", line 692, in reraise
raise value.with_traceback(tb)
File "/Users/andyw/frontend_data/venv/lib/python3.6/site-packages/google/cloud/datastore/_gax.py", line 74, in _catch_remap_gax_error
yield
File "/Users/andyw/frontend_data/venv/lib/python3.6/site-packages/google/cloud/datastore/_gax.py", line 134, in run_query
return super(GAPICDatastoreAPI, self).run_query(*args, **kwargs)
File "/Users/andyw/frontend_data/venv/lib/python3.6/site-packages/google/cloud/gapic/datastore/v1/datastore_client.py", line 258, in run_query
return self._run_query(request, options)
File "/Users/andyw/frontend_data/venv/lib/python3.6/site-packages/google/gax/api_callable.py", line 452, in inner
return api_caller(api_call, this_settings, request)
File "/Users/andyw/frontend_data/venv/lib/python3.6/site-packages/google/gax/api_callable.py", line 438, in base_caller
return api_call(*args)
File "/Users/andyw/frontend_data/venv/lib/python3.6/site-packages/google/gax/api_callable.py", line 376, in inner
return a_func(*args, **kwargs)
File "/Users/andyw/frontend_data/venv/lib/python3.6/site-packages/google/gax/retry.py", line 127, in inner
' classified as transient', exception)
google.api_core.exceptions.PreconditionFailed: 412 no matching index found. recommended index is:
- kind: WeatherData
ancestor: yes
properties:
- name: time
答案 0 :(得分:1)
两个回溯都有相同的根本原因:
no matching index found. recommended index is:
- kind: WeatherData
ancestor: yes
properties:
- name: time
基本上,您的查询需要在数据存储区索引配置中找不到的复合索引(恰好是消息中包含的索引)。您需要将该索引定义添加到index.yaml
配置文件中并(重新)部署该文件。
来自About index.yaml(感兴趣的整个文档页面):
应用程序发出的每个云数据存储区查询都需要一个 相应的指数。简单查询的索引,例如查询 单个属性是自动创建的。复杂指数 必须在名为
index.yaml
的配置文件中定义查询。 此文件随应用程序一起上载,以在Cloud中创建索引 数据存储。
注意:虽然您的查询可能显示在一个属性time
上,但它不是:它也是一个祖先查询,{{ 1}}祖先作为附加财产。因此,您的查询需要一个复合索引。