def read_row(self, row_key, filter_=None): """Read a single row from this table. :type row_key: bytes :param row_key: The key of the row to read from. :type filter_: :class:`.RowFilter` :param filter_: (Optional) The filter to apply to the contents of the row. If unset, returns the entire row. :rtype: :class:`.PartialRowData`, :data:`NoneType <types.NoneType>` :returns: The contents of the row if any chunks were returned in the response, otherwise :data:`None`. :raises: :class:`ValueError <exceptions.ValueError>` if a commit row chunk is never encountered. """ request_pb = _create_row_request(self.name, row_key=row_key, filter_=filter_, app_profile_id=self._app_profile_id) data_client = self._instance._client.table_data_client if 'read_rows' not in data_client._inner_api_calls: default_retry = data_client._method_configs['ReadRows'].retry timeout = data_client._method_configs['ReadRows'].timeout data_client._inner_api_calls['read_rows'] = \ wrap_method( data_client.transport.read_rows, default_retry=default_retry, default_timeout=timeout, client_info=data_client._client_info, ) rows_data = PartialRowsData(data_client._inner_api_calls['read_rows'], request_pb) rows_data.consume_all() if rows_data.state not in (rows_data.NEW_ROW, rows_data.START): raise ValueError('The row remains partial / is not committed.') if len(rows_data.rows) == 0: return None return rows_data.rows[row_key]
def _do_mutate_retryable_rows(self): """Mutate all the rows that are eligible for retry. A row is eligible for retry if it has not been tried or if it resulted in a transient error in a previous call. :rtype: list :return: The responses statuses, which is a list of :class:`~google.rpc.status_pb2.Status`. :raises: One of the following: * :exc:`~.table._BigtableRetryableError` if any row returned a transient error. * :exc:`RuntimeError` if the number of responses doesn't match the number of rows that were retried """ retryable_rows = [] index_into_all_rows = [] for index, status in enumerate(self.responses_statuses): if self._is_retryable(status): retryable_rows.append(self.rows[index]) index_into_all_rows.append(index) if not retryable_rows: # All mutations are either successful or non-retryable now. return self.responses_statuses mutate_rows_request = _mutate_rows_request( self.table_name, retryable_rows, app_profile_id=self.app_profile_id) data_client = self.client.table_data_client inner_api_calls = data_client._inner_api_calls if "mutate_rows" not in inner_api_calls: default_retry = (data_client._method_configs["MutateRows"].retry, ) if self.timeout is None: default_timeout = data_client._method_configs[ "MutateRows"].timeout else: default_timeout = timeout.ExponentialTimeout( deadline=self.timeout) data_client._inner_api_calls["mutate_rows"] = wrap_method( data_client.transport.mutate_rows, default_retry=default_retry, default_timeout=default_timeout, client_info=data_client._client_info, ) responses = data_client._inner_api_calls["mutate_rows"]( mutate_rows_request, retry=None) num_responses = 0 num_retryable_responses = 0 for response in responses: for entry in response.entries: num_responses += 1 index = index_into_all_rows[entry.index] self.responses_statuses[index] = entry.status if self._is_retryable(entry.status): num_retryable_responses += 1 if entry.status.code == 0: self.rows[index].clear() if len(retryable_rows) != num_responses: raise RuntimeError( "Unexpected number of responses", num_responses, "Expected", len(retryable_rows), ) if num_retryable_responses: raise _BigtableRetryableError return self.responses_statuses
def _do_mutate_retryable_rows(self): """Mutate all the rows that are eligible for retry. A row is eligible for retry if it has not been tried or if it resulted in a transient error in a previous call. :rtype: list :return: The responses statuses, which is a list of :class:`~google.rpc.status_pb2.Status`. :raises: One of the following: * :exc:`~.table._BigtableRetryableError` if any row returned a transient error. * :exc:`RuntimeError` if the number of responses doesn't match the number of rows that were retried """ retryable_rows = [] index_into_all_rows = [] for index, status in enumerate(self.responses_statuses): if self._is_retryable(status): retryable_rows.append(self.rows[index]) index_into_all_rows.append(index) if not retryable_rows: # All mutations are either successful or non-retryable now. return self.responses_statuses mutate_rows_request = _mutate_rows_request( self.table_name, retryable_rows, app_profile_id=self.app_profile_id ) data_client = self.client.table_data_client inner_api_calls = data_client._inner_api_calls if "mutate_rows" not in inner_api_calls: default_retry = (data_client._method_configs["MutateRows"].retry,) if self.timeout is None: default_timeout = data_client._method_configs["MutateRows"].timeout else: default_timeout = timeout.ExponentialTimeout(deadline=self.timeout) data_client._inner_api_calls["mutate_rows"] = wrap_method( data_client.transport.mutate_rows, default_retry=default_retry, default_timeout=default_timeout, client_info=data_client._client_info, ) responses = data_client._inner_api_calls["mutate_rows"]( mutate_rows_request, retry=None ) num_responses = 0 num_retryable_responses = 0 for response in responses: for entry in response.entries: num_responses += 1 index = index_into_all_rows[entry.index] self.responses_statuses[index] = entry.status if self._is_retryable(entry.status): num_retryable_responses += 1 if entry.status.code == 0: self.rows[index].clear() if len(retryable_rows) != num_responses: raise RuntimeError( "Unexpected number of responses", num_responses, "Expected", len(retryable_rows), ) if num_retryable_responses: raise _BigtableRetryableError return self.responses_statuses