예제 #1
0
    def lookup(self, dataset_id, key_pbs):
        """Lookup keys from a dataset in the Cloud Datastore.

    This method deals only with protobufs
    (:class:`gcloud.datastore.datastore_v1_pb2.Key`
    and
    :class:`gcloud.datastore.datastore_v1_pb2.Entity`)
    and is used under the hood for methods like
    :func:`gcloud.datastore.dataset.Dataset.get_entity`:

    >>> import gcloud.datastore
    >>> from gcloud.datastore.key import Key
    >>> connection = gcloud.datastore.get_connection(email, key_path)
    >>> dataset = connection.dataset('dataset-id')
    >>> key = Key(dataset=dataset).kind('MyKind').id(1234)

    Using the :class:`gcloud.datastore.dataset.Dataset` helper:

    >>> dataset.get_entity(key)
    <Entity object>

    Using the ``connection`` class directly:

    >>> connection.lookup('dataset-id', key.to_protobuf())
    <Entity protobuf>

    :type dataset_id: string
    :param dataset_id: The dataset to look up the keys.

    :type key_pbs: list of :class:`gcloud.datastore.datastore_v1_pb2.Key`
                   (or a single Key)
    :param key_pbs: The key (or keys) to retrieve from the datastore.

    :rtype: list of :class:`gcloud.datastore.datastore_v1_pb2.Entity`
            (or a single Entity)
    :returns: The entities corresponding to the keys provided.
              If a single key was provided and no results matched,
              this will return None.
              If multiple keys were provided and no results matched,
              this will return an empty list.
    """
        lookup_request = datastore_pb.LookupRequest()

        single_key = isinstance(key_pbs, datastore_pb.Key)

        if single_key:
            key_pbs = [key_pbs]

        for key_pb in key_pbs:
            lookup_request.key.add().CopyFrom(key_pb)

        lookup_response = self._rpc(dataset_id, 'lookup', lookup_request,
                                    datastore_pb.LookupResponse)

        results = [result.entity for result in lookup_response.found]

        if single_key:
            if results:
                return results[0]
            else:
                return None

        return results
예제 #2
0
    def lookup(self, dataset_id, key_pbs, missing=None, deferred=None):
        """Lookup keys from a dataset in the Cloud Datastore.

        Maps the ``DatastoreService.Lookup`` protobuf RPC.

        This method deals only with protobufs
        (:class:`gcloud.datastore.datastore_v1_pb2.Key` and
        :class:`gcloud.datastore.datastore_v1_pb2.Entity`) and is used
        under the hood for methods like
        :func:`gcloud.datastore.dataset.Dataset.get_entity`:

        >>> from gcloud import datastore
        >>> from gcloud.datastore.key import Key
        >>> connection = datastore.get_connection()
        >>> dataset = connection.dataset('dataset-id')
        >>> key = Key(dataset=dataset).kind('MyKind').id(1234)

        Using the :class:`gcloud.datastore.dataset.Dataset` helper:

        >>> dataset.get_entity(key)
        <Entity object>

        Using the ``connection`` class directly:

        >>> connection.lookup('dataset-id', key.to_protobuf())
        <Entity protobuf>

        :type dataset_id: string
        :param dataset_id: The dataset to look up the keys.

        :type key_pbs: list of :class:`gcloud.datastore.datastore_v1_pb2.Key`
                       (or a single Key)
        :param key_pbs: The key (or keys) to retrieve from the datastore.

        :type missing: an empty list or None.
        :param missing: If a list is passed, the key-only entity protobufs
                        returned by the backend as "missing" will be copied
                        into it.  Use only as a keyword param.

        :type deferred: an empty list or None.
        :param deferred: If a list is passed, the key protobufs returned
                        by the backend as "deferred" will be copied into it.
                        Use only as a keyword param.

        :rtype: list of :class:`gcloud.datastore.datastore_v1_pb2.Entity`
                (or a single Entity)
        :returns: The entities corresponding to the keys provided.
                  If a single key was provided and no results matched,
                  this will return None.
                  If multiple keys were provided and no results matched,
                  this will return an empty list.
        """
        if missing is not None and missing != []:
            raise ValueError('missing must be None or an empty list')

        if deferred is not None and deferred != []:
            raise ValueError('deferred must be None or an empty list')

        lookup_request = datastore_pb.LookupRequest()

        single_key = isinstance(key_pbs, datastore_pb.Key)

        if single_key:
            key_pbs = [key_pbs]

        for key_pb in key_pbs:
            lookup_request.key.add().CopyFrom(key_pb)

        results = []
        while True:  # loop against possible deferred.
            lookup_response = self._rpc(dataset_id, 'lookup', lookup_request,
                                        datastore_pb.LookupResponse)

            results.extend([result.entity for result in lookup_response.found])

            if missing is not None:
                missing.extend(
                    [result.entity for result in lookup_response.missing])

            if deferred is not None:
                deferred.extend([key for key in lookup_response.deferred])
                break

            if not lookup_response.deferred:
                break

            # We have deferred keys, and the user didn't ask to know about
            # them, so retry (but only with the deferred ones).
            _copy_deferred_keys(lookup_request, lookup_response)

        if single_key:
            if results:
                return results[0]
            else:
                return None

        return results
예제 #3
0
    def lookup(self,
               dataset_id,
               key_pbs,
               missing=None,
               deferred=None,
               eventual=False):
        """Lookup keys from a dataset in the Cloud Datastore.

        Maps the ``DatastoreService.Lookup`` protobuf RPC.

        This method deals only with protobufs
        (:class:`gcloud.datastore.datastore_v1_pb2.Key` and
        :class:`gcloud.datastore.datastore_v1_pb2.Entity`) and is used
        under the hood for methods like
        :func:`gcloud.datastore.dataset.Dataset.get_entity`:

        >>> from gcloud import datastore
        >>> from gcloud.datastore.key import Key
        >>> connection = datastore.get_connection()
        >>> dataset = connection.dataset('dataset-id')
        >>> key = Key(dataset=dataset).kind('MyKind').id(1234)

        Using the :class:`gcloud.datastore.dataset.Dataset` helper:

        >>> dataset.get_entity(key)
        <Entity object>

        Using the ``connection`` class directly:

        >>> connection.lookup('dataset-id', key.to_protobuf())
        <Entity protobuf>

        :type dataset_id: string
        :param dataset_id: The dataset to look up the keys.

        :type key_pbs: list of :class:`gcloud.datastore.datastore_v1_pb2.Key`
                       (or a single Key)
        :param key_pbs: The key (or keys) to retrieve from the datastore.

        :type missing: an empty list or None.
        :param missing: If a list is passed, the key-only entity protobufs
                        returned by the backend as "missing" will be copied
                        into it.  Use only as a keyword param.

        :type deferred: an empty list or None.
        :param deferred: If a list is passed, the key protobufs returned
                        by the backend as "deferred" will be copied into it.
                        Use only as a keyword param.

        :type eventual: bool
        :param eventual: If False (the default), request ``STRONG`` read
                        consistency.  If True, request ``EVENTUAL`` read
                        consistency.  If the connection has a current
                        transaction, this value *must* be false.

        :rtype: list of :class:`gcloud.datastore.datastore_v1_pb2.Entity`
                (or a single Entity)
        :returns: The entities corresponding to the keys provided.
                  If a single key was provided and no results matched,
                  this will return None.
                  If multiple keys were provided and no results matched,
                  this will return an empty list.
        :raises: ValueError if ``eventual`` is True
        """
        if missing is not None and missing != []:
            raise ValueError('missing must be None or an empty list')

        if deferred is not None and deferred != []:
            raise ValueError('deferred must be None or an empty list')

        lookup_request = datastore_pb.LookupRequest()
        self._set_read_options(lookup_request, eventual)

        single_key = isinstance(key_pbs, datastore_pb.Key)

        if single_key:
            key_pbs = [key_pbs]

        for key_pb in key_pbs:
            lookup_request.key.add().CopyFrom(key_pb)

        results, missing_found, deferred_found = self._lookup(
            lookup_request, dataset_id, deferred is not None)

        if missing is not None:
            missing.extend(missing_found)

        if deferred is not None:
            deferred.extend(deferred_found)

        if single_key:
            if results:
                return results[0]
            else:
                return None

        return results