def _datastore_commit(mutations, transaction, retries=None, timeout=None): """Call Commit on Datastore. Args: mutations (List[datastore_pb2.Mutation]): The changes to persist to Datastore. transaction (Union[bytes, NoneType]): The identifier for the transaction for this commit, or :data:`None` if no transaction is being used. retries (int): Number of times to potentially retry the call. If :data:`None` is passed, will use :data:`_retry._DEFAULT_RETRIES`. If :data:`0` is passed, the call is attempted only once. timeout (float): Timeout, in seconds, to pass to gRPC call. If :data:`None` is passed, will use :data:`_DEFAULT_TIMEOUT`. Returns: tasklets.Tasklet: A future for :class:`google.cloud.datastore_v1.datastore_pb2.CommitResponse` """ if transaction is None: mode = datastore_pb2.CommitRequest.NON_TRANSACTIONAL else: mode = datastore_pb2.CommitRequest.TRANSACTIONAL client = context_module.get_context().client request = datastore_pb2.CommitRequest( project_id=client.project, mode=mode, mutations=mutations, transaction=transaction, ) return make_call("Commit", request, retries=retries, timeout=timeout)
def _datastore_commit(mutations, transaction): """Call Commit on Datastore. Args: mutations (List[datastore_pb2.Mutation]): The changes to persist to Datastore. transaction (Union[bytes, NoneType]): The identifier for the transaction for this commit, or :data:`None` if no transaction is being used. Returns: grpc.Future: A future for :class:`google.cloud.datastore_v1.datastore_pb2.CommitResponse` """ if transaction is None: mode = datastore_pb2.CommitRequest.NON_TRANSACTIONAL else: mode = datastore_pb2.CommitRequest.TRANSACTIONAL client = _runstate.current().client request = datastore_pb2.CommitRequest( project_id=client.project, mode=mode, mutations=mutations, transaction=transaction, ) api = stub() return api.Commit.future(request)
def test_commit_w_transaction(self): from google.cloud.datastore_v1.proto import datastore_pb2 from google.cloud.datastore.helpers import _new_value_pb project = 'PROJECT' key_pb = _make_key_pb(project) rsp_pb = datastore_pb2.CommitResponse() req_pb = datastore_pb2.CommitRequest() mutation = req_pb.mutations.add() insert = mutation.upsert insert.key.CopyFrom(key_pb) value_pb = _new_value_pb(insert, 'foo') value_pb.string_value = u'Foo' # 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. rq_class = datastore_pb2.CommitRequest ds_api = self._make_one(client) mode = rq_class.TRANSACTIONAL result = ds_api.commit(project, mode, [mutation], transaction=b'xact') # Check the result and verify the callers. self.assertEqual(result, rsp_pb) uri = _build_expected_url(client._base_url, project, 'commit') request = _verify_protobuf_call(http, uri, rq_class()) self.assertEqual(request.transaction, b'xact') self.assertEqual(list(request.mutations), [mutation]) self.assertEqual(request.mode, rq_class.TRANSACTIONAL)
def commit(self, project, mode, mutations, transaction=None): """Perform a ``commit`` request. :type project: str :param project: The project to connect to. This is usually your project name in the cloud console. :type mode: :class:`.gapic.datastore.v1.enums.CommitRequest.Mode` :param mode: The type of commit to perform. Expected to be one of ``TRANSACTIONAL`` or ``NON_TRANSACTIONAL``. :type mutations: list :param mutations: List of :class:`.datastore_pb2.Mutation`, the mutations to perform. :type transaction: bytes :param transaction: (Optional) The transaction ID returned from :meth:`begin_transaction`. Non-transactional commits must pass :data:`None`. :rtype: :class:`.datastore_pb2.CommitResponse` :returns: The returned protobuf response object. """ request_pb = _datastore_pb2.CommitRequest( project_id=project, mode=mode, transaction=transaction, mutations=mutations, ) return _rpc(self.client._http, project, 'commit', self.client._base_url, request_pb, _datastore_pb2.CommitResponse)
def test_commit(self): # Setup Expected Response index_updates = 1425228195 expected_response = {'index_updates': index_updates} expected_response = datastore_pb2.CommitResponse(**expected_response) # Mock the API response channel = ChannelStub(responses=[expected_response]) client = datastore_v1.DatastoreClient(channel=channel) # Setup Request project_id = 'projectId-1969970175' mode = enums.CommitRequest.Mode.MODE_UNSPECIFIED mutations = [] response = client.commit(project_id, mode, mutations) assert expected_response == response assert len(channel.requests) == 1 expected_request = datastore_pb2.CommitRequest(project_id=project_id, mode=mode, mutations=mutations) actual_request = channel.requests[0][1] assert expected_request == actual_request
def commit(self, project_id, mode, mutations, transaction=None, retry=google.api_core.gapic_v1.method.DEFAULT, timeout=google.api_core.gapic_v1.method.DEFAULT, metadata=None): """ Commits a transaction, optionally creating, deleting or modifying some entities. Example: >>> from google.cloud import datastore_v1 >>> from google.cloud.datastore_v1 import enums >>> >>> client = datastore_v1.DatastoreClient() >>> >>> # TODO: Initialize `project_id`: >>> project_id = '' >>> >>> # TODO: Initialize `mode`: >>> mode = enums.CommitRequest.Mode.MODE_UNSPECIFIED >>> >>> # TODO: Initialize `mutations`: >>> mutations = [] >>> >>> response = client.commit(project_id, mode, mutations) Args: project_id (str): The ID of the project against which to make the request. mode (~google.cloud.datastore_v1.types.Mode): The type of commit to perform. Defaults to ``TRANSACTIONAL``. mutations (list[Union[dict, ~google.cloud.datastore_v1.types.Mutation]]): The mutations to perform. When mode is ``TRANSACTIONAL``, mutations affecting a single entity are applied in order. The following sequences of mutations affecting a single entity are not permitted in a single ``Commit`` request: - ``insert`` followed by ``insert`` - ``update`` followed by ``insert`` - ``upsert`` followed by ``insert`` - ``delete`` followed by ``update`` When mode is ``NON_TRANSACTIONAL``, no two mutations may affect a single entity. If a dict is provided, it must be of the same form as the protobuf message :class:`~google.cloud.datastore_v1.types.Mutation` transaction (bytes): The identifier of the transaction associated with the commit. A transaction identifier is returned by a call to ``Datastore.BeginTransaction``. 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.CommitResponse` 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 'commit' not in self._inner_api_calls: self._inner_api_calls[ 'commit'] = google.api_core.gapic_v1.method.wrap_method( self.transport.commit, default_retry=self._method_configs['Commit'].retry, default_timeout=self._method_configs['Commit'].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(transaction=transaction, ) request = datastore_pb2.CommitRequest( project_id=project_id, mode=mode, mutations=mutations, transaction=transaction, ) return self._inner_api_calls['commit'](request, retry=retry, timeout=timeout, metadata=metadata)