Google数据存储区API查询祖先过滤器

时间:2018-01-26 20:05:57

标签: python google-cloud-datastore

我正在尝试使用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

1 个答案:

答案 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}}祖先作为附加财产。因此,您的查询需要一个复合索引。