def _datastore_run_query(query): """Run a query in Datastore. Args: query (query.QueryOptions): The query spec. Returns: tasklets.Future: """ query_pb = _query_to_protobuf(query) partition_id = entity_pb2.PartitionId(project_id=query.project, namespace_id=query.namespace) read_options = _datastore_api.get_read_options( query, default_read_consistency=_datastore_api.EVENTUAL) request = datastore_pb2.RunQueryRequest( project_id=query.project, partition_id=partition_id, query=query_pb, read_options=read_options, ) response = yield _datastore_api.make_call("RunQuery", request, timeout=query.timeout) log.debug(response) return response
def run_query(self, project_id, partition_id, read_options=None, query=None, gql_query=None): """Perform a ``runQuery`` request. :type project_id: str :param project_id: The project to connect to. This is usually your project name in the cloud console. :type partition_id: :class:`.entity_pb2.PartitionId` :param partition_id: Partition ID corresponding to an optional namespace and project ID. :type read_options: :class:`.datastore_pb2.ReadOptions` :param read_options: (Optional) The options for this query. Contains either the transaction for the read or ``STRONG`` or ``EVENTUAL`` read consistency. :type query: :class:`.query_pb2.Query` :param query: (Optional) The query protobuf to run. At most one of ``query`` and ``gql_query`` can be specified. :type gql_query: :class:`.query_pb2.GqlQuery` :param gql_query: (Optional) The GQL query to run. At most one of ``query`` and ``gql_query`` can be specified. :rtype: :class:`.datastore_pb2.RunQueryResponse` :returns: The returned protobuf response object. """ request_pb = _datastore_pb2.RunQueryRequest( project_id=project_id, partition_id=partition_id, read_options=read_options, query=query, gql_query=gql_query, ) return _rpc( self.client._http, project_id, "runQuery", self.client._base_url, self.client._client_info, request_pb, _datastore_pb2.RunQueryResponse, )
def test_run_query_w_eventual_no_transaction(self): from google.cloud.datastore_v1.proto import datastore_pb2 from google.cloud.datastore_v1.proto import entity_pb2 from google.cloud.datastore_v1.proto import query_pb2 project = "PROJECT" kind = "Nonesuch" cursor = b"\x00" query_pb = self._make_query_pb(kind) partition_id = entity_pb2.PartitionId(project_id=project) read_options = datastore_pb2.ReadOptions( read_consistency=datastore_pb2.ReadOptions.EVENTUAL ) rsp_pb = datastore_pb2.RunQueryResponse( batch=query_pb2.QueryResultBatch( entity_result_type=query_pb2.EntityResult.FULL, end_cursor=cursor, more_results=query_pb2.QueryResultBatch.NO_MORE_RESULTS, ) ) # Create mock HTTP and client with response. http = _make_requests_session( [_make_response(content=rsp_pb.SerializeToString())] ) client_info = _make_client_info() client = mock.Mock( _http=http, _base_url="test.invalid", _client_info=client_info, spec=["_http", "_base_url", "_client_info"], ) # Make request. ds_api = self._make_one(client) response = ds_api.run_query(project, partition_id, read_options, query=query_pb) # Check the result and verify the callers. self.assertEqual(response, rsp_pb) uri = _build_expected_url(client._base_url, project, "runQuery") request = _verify_protobuf_call(http, uri, datastore_pb2.RunQueryRequest()) self.assertEqual(request.partition_id, partition_id) self.assertEqual(request.query, query_pb) self.assertEqual(request.read_options, read_options)
def test_it(_datastore_api): query = query_module.QueryOptions(project="testing", namespace="") query_pb = _datastore_query._query_to_protobuf(query) _datastore_api.make_call.return_value = utils.future_result("foo") read_options = datastore_pb2.ReadOptions() request = datastore_pb2.RunQueryRequest( project_id="testing", partition_id=entity_pb2.PartitionId(project_id="testing", namespace_id=""), query=query_pb, read_options=read_options, ) _datastore_api.get_read_options.return_value = read_options assert _datastore_query._datastore_run_query(query).result() == "foo" _datastore_api.make_call.assert_called_once_with("RunQuery", request, timeout=None) _datastore_api.get_read_options.assert_called_once_with( query, default_read_consistency=_datastore_api.EVENTUAL)
def test_run_query_w_namespace_nonempty_result(self): from google.cloud.datastore_v1.proto import datastore_pb2 from google.cloud.datastore_v1.proto import entity_pb2 from google.cloud.datastore_v1.proto import query_pb2 project = "PROJECT" kind = "Kind" namespace = "NS" query_pb = self._make_query_pb(kind) partition_id = entity_pb2.PartitionId(project_id=project, namespace_id=namespace) read_options = datastore_pb2.ReadOptions() rsp_pb = datastore_pb2.RunQueryResponse( batch=query_pb2.QueryResultBatch( entity_result_type=query_pb2.EntityResult.FULL, entity_results=[ query_pb2.EntityResult(entity=entity_pb2.Entity()) ], more_results=query_pb2.QueryResultBatch.NO_MORE_RESULTS, )) # Create mock HTTP and client with response. http = _make_requests_session( [_make_response(content=rsp_pb.SerializeToString())]) client = mock.Mock(_http=http, _base_url="test.invalid", spec=["_http", "_base_url"]) # Make request. ds_api = self._make_one(client) response = ds_api.run_query(project, partition_id, read_options, query=query_pb) # Check the result and verify the callers. self.assertEqual(response, rsp_pb) uri = _build_expected_url(client._base_url, project, "runQuery") request = _verify_protobuf_call(http, uri, datastore_pb2.RunQueryRequest()) self.assertEqual(request.partition_id, partition_id) self.assertEqual(request.query, query_pb)
def test_run_query(self): # Setup Expected Response expected_response = {} expected_response = datastore_pb2.RunQueryResponse(**expected_response) # Mock the API response channel = ChannelStub(responses=[expected_response]) client = datastore_v1.DatastoreClient(channel=channel) # Setup Request project_id = 'projectId-1969970175' partition_id = {} response = client.run_query(project_id, partition_id) assert expected_response == response assert len(channel.requests) == 1 expected_request = datastore_pb2.RunQueryRequest( project_id=project_id, partition_id=partition_id) actual_request = channel.requests[0][1] assert expected_request == actual_request
def test_run_query_wo_eventual_w_transaction(self): from google.cloud.datastore_v1.proto import datastore_pb2 from google.cloud.datastore_v1.proto import entity_pb2 from google.cloud.datastore_v1.proto import query_pb2 project = 'PROJECT' kind = 'Nonesuch' cursor = b'\x00' transaction = b'TRANSACTION' query_pb = self._make_query_pb(kind) partition_id = entity_pb2.PartitionId(project_id=project) read_options = datastore_pb2.ReadOptions(transaction=transaction) rsp_pb = datastore_pb2.RunQueryResponse( batch=query_pb2.QueryResultBatch( entity_result_type=query_pb2.EntityResult.FULL, end_cursor=cursor, more_results=query_pb2.QueryResultBatch.NO_MORE_RESULTS, ) ) # Create mock HTTP and client with response. http = _make_requests_session( [_make_response(content=rsp_pb.SerializeToString())]) client = mock.Mock( _http=http, _base_url='test.invalid', spec=['_http', '_base_url']) # Make request. ds_api = self._make_one(client) response = ds_api.run_query( project, partition_id, read_options, query=query_pb) # Check the result and verify the callers. self.assertEqual(response, rsp_pb) uri = _build_expected_url(client._base_url, project, 'runQuery') request = _verify_protobuf_call( http, uri, datastore_pb2.RunQueryRequest()) self.assertEqual(request.partition_id, partition_id) self.assertEqual(request.query, query_pb) self.assertEqual(request.read_options, read_options)
def _run_query(project_id, namespace, query_pb): """Run a query in Datastore. Will potentially repeat the query to get all results. Args: project_id (str): The project/app id of the Datastore instance. namespace (str): The namespace to which to restrict results. query_pb (query_pb2.Query): The query protocol buffer representation. Returns: tasklets.Future: List[Tuple[query_pb2.EntityResult.ResultType, query_pb2.EntityResult]]: The raw query results. """ results = [] partition_id = entity_pb2.PartitionId(project_id=project_id, namespace_id=namespace) while True: # See what results we get from the backend request = datastore_pb2.RunQueryRequest(project_id=project_id, partition_id=partition_id, query=query_pb) response = yield _datastore_api.make_call("RunQuery", request) log.debug(response) batch = response.batch results.extend(((batch.entity_result_type, result) for result in batch.entity_results)) # Did we get all of them? if batch.more_results != MORE_RESULTS_TYPE_NOT_FINISHED: break # Still some results left to fetch. Update cursors and try again. query_pb.start_cursor = batch.end_cursor return results
def _datastore_run_query(query): """Run a query in Datastore. Args: query (query.QueryOptions): The query spec. Returns: tasklets.Future: """ query_pb = _query_to_protobuf(query) partition_id = entity_pb2.PartitionId(project_id=query.project, namespace_id=query.namespace) read_options = _datastore_api.get_read_options(query) request = datastore_pb2.RunQueryRequest( project_id=query.project, partition_id=partition_id, query=query_pb, read_options=read_options, ) response = yield _datastore_api.make_call("RunQuery", request, timeout=query.timeout) utils.logging_debug(log, response) raise tasklets.Return(response)
def run_query(self, project_id, partition_id, read_options=None, query=None, gql_query=None, retry=google.api_core.gapic_v1.method.DEFAULT, timeout=google.api_core.gapic_v1.method.DEFAULT, metadata=None): """ Queries for entities. Example: >>> from google.cloud import datastore_v1 >>> >>> client = datastore_v1.DatastoreClient() >>> >>> # TODO: Initialize `project_id`: >>> project_id = '' >>> >>> # TODO: Initialize `partition_id`: >>> partition_id = {} >>> >>> response = client.run_query(project_id, partition_id) Args: project_id (str): The ID of the project against which to make the request. partition_id (Union[dict, ~google.cloud.datastore_v1.types.PartitionId]): Entities are partitioned into subsets, identified by a partition ID. Queries are scoped to a single partition. This partition ID is normalized with the standard default context partition ID. If a dict is provided, it must be of the same form as the protobuf message :class:`~google.cloud.datastore_v1.types.PartitionId` read_options (Union[dict, ~google.cloud.datastore_v1.types.ReadOptions]): The options for this query. If a dict is provided, it must be of the same form as the protobuf message :class:`~google.cloud.datastore_v1.types.ReadOptions` query (Union[dict, ~google.cloud.datastore_v1.types.Query]): The query to run. If a dict is provided, it must be of the same form as the protobuf message :class:`~google.cloud.datastore_v1.types.Query` gql_query (Union[dict, ~google.cloud.datastore_v1.types.GqlQuery]): The GQL query to run. If a dict is provided, it must be of the same form as the protobuf message :class:`~google.cloud.datastore_v1.types.GqlQuery` retry (Optional[google.api_core.retry.Retry]): A retry object used to retry requests. If ``None`` is specified, requests will not be retried. timeout (Optional[float]): The amount of time, in seconds, to wait for the request to complete. Note that if ``retry`` is specified, the timeout applies to each individual attempt. metadata (Optional[Sequence[Tuple[str, str]]]): Additional metadata that is provided to the method. Returns: A :class:`~google.cloud.datastore_v1.types.RunQueryResponse` instance. Raises: google.api_core.exceptions.GoogleAPICallError: If the request failed for any reason. google.api_core.exceptions.RetryError: If the request failed due to a retryable error and retry attempts failed. ValueError: If the parameters are invalid. """ # Wrap the transport method to add retry and timeout logic. if 'run_query' not in self._inner_api_calls: self._inner_api_calls[ 'run_query'] = google.api_core.gapic_v1.method.wrap_method( self.transport.run_query, default_retry=self._method_configs['RunQuery'].retry, default_timeout=self._method_configs['RunQuery'].timeout, client_info=self._client_info, ) # Sanity check: We have some fields which are mutually exclusive; # raise ValueError if more than one is sent. google.api_core.protobuf_helpers.check_oneof( query=query, gql_query=gql_query, ) request = datastore_pb2.RunQueryRequest( project_id=project_id, partition_id=partition_id, read_options=read_options, query=query, gql_query=gql_query, ) return self._inner_api_calls['run_query'](request, retry=retry, timeout=timeout, metadata=metadata)