예제 #1
0
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,
        )
예제 #3
0
    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)
예제 #6
0
    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
예제 #7
0
    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)
예제 #8
0
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
예제 #9
0
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)