def transaction(self): """Proxy to :class:`gcloud.datastore.transaction.Transaction`. Passes our ``dataset_id``. """ return Transaction(dataset_id=self.dataset_id, connection=self.connection)
def next_page(self): """Fetch a single "page" of query results. Low-level API for fine control: the more convenient API is to iterate on the current Iterator. :rtype: tuple, (entities, more_results, cursor) """ pb = _pb_from_query(self._query) start_cursor = self._start_cursor if start_cursor is not None: pb.start_cursor = base64.b64decode(start_cursor) end_cursor = self._end_cursor if end_cursor is not None: pb.end_cursor = base64.b64decode(end_cursor) if self._limit is not None: pb.limit = self._limit pb.offset = self._offset transaction = Transaction.current() query_results = self._connection.run_query( query_pb=pb, dataset_id=self._query.dataset_id, namespace=self._query.namespace, transaction_id=transaction and transaction.id, ) # NOTE: `query_results` contains an extra value that we don't use, # namely `skipped_results`. # # NOTE: The value of `more_results` is not currently useful because # the back-end always returns an enum # value of MORE_RESULTS_AFTER_LIMIT even if there are no more # results. See # https://github.com/GoogleCloudPlatform/gcloud-python/issues/280 # for discussion. entity_pbs, cursor_as_bytes, more_results_enum = query_results[:3] self._start_cursor = base64.b64encode(cursor_as_bytes) self._end_cursor = None if more_results_enum == self._NOT_FINISHED: self._more_results = True elif more_results_enum in self._FINISHED: self._more_results = False else: raise ValueError('Unexpected value returned for `more_results`.') self._page = [ helpers.entity_from_protobuf(entity) for entity in entity_pbs ] return self._page, self._more_results, self._start_cursor
def next_page(self): """Fetch a single "page" of query results. Low-level API for fine control: the more convenient API is to iterate on the current Iterator. :rtype: tuple, (entities, more_results, cursor) """ pb = _pb_from_query(self._query) start_cursor = self._start_cursor if start_cursor is not None: pb.start_cursor = base64.b64decode(start_cursor) end_cursor = self._end_cursor if end_cursor is not None: pb.end_cursor = base64.b64decode(end_cursor) if self._limit is not None: pb.limit = self._limit pb.offset = self._offset transaction = Transaction.current() query_results = self._connection.run_query( query_pb=pb, dataset_id=self._query.dataset_id, namespace=self._query.namespace, transaction_id=transaction and transaction.id, ) # NOTE: `query_results` contains an extra value that we don't use, # namely `skipped_results`. # # NOTE: The value of `more_results` is not currently useful because # the back-end always returns an enum # value of MORE_RESULTS_AFTER_LIMIT even if there are no more # results. See # https://github.com/GoogleCloudPlatform/gcloud-python/issues/280 # for discussion. entity_pbs, cursor_as_bytes, more_results_enum = query_results[:3] self._start_cursor = base64.b64encode(cursor_as_bytes) self._end_cursor = None if more_results_enum == self._NOT_FINISHED: self._more_results = True elif more_results_enum in self._FINISHED: self._more_results = False else: raise ValueError('Unexpected value returned for `more_results`.') self._page = [ helpers.entity_from_protobuf(entity) for entity in entity_pbs] return self._page, self._more_results, self._start_cursor
def delete_report(employee_id, report_id, force): with Transaction(): report = _get_report(employee_id, report_id, False) if report is None: raise NoSuchReport() if report['status'] != 'pending' and not force: raise BadReportStatus(report['status']) count = _purge_report_items(report) datastore.delete([report.key]) return count
def create_report(employee_id, report_id, rows, description): with Transaction(): if _get_report(employee_id, report_id, False) is not None: raise DuplicateReport() report = _upsert_report(employee_id, report_id, rows) report['status'] = 'pending' if description is not None: report['description'] = description report['created'] = report['updated'] = datetime.datetime.utcnow() datastore.put([report])
def reject_report(employee_id, report_id, reason): with Transaction(): report = _get_report(employee_id, report_id, False) if report is None: raise NoSuchReport() if report['status'] != 'pending': raise BadReportStatus(report['status']) report['updated'] = datetime.datetime.utcnow() report['status'] = 'rejected' report['reason'] = reason datastore.put([report])
def approve_report(employee_id, report_id, check_number): with Transaction(): report = _get_report(employee_id, report_id, False) if report is None: raise NoSuchReport() if report['status'] != 'pending': raise BadReportStatus(report['status']) report['updated'] = datetime.datetime.utcnow() report['status'] = 'paid' report['check_number'] = check_number datastore.put([report])
def transaction(self, *args, **kwargs): """Create a transaction bound to this dataset. :param args: positional arguments, passed through to the Transaction :param kw: keyword arguments, passed through to the Transaction :rtype: :class:`gcloud.datastore.transaction.Transaction` :returns: a new Transaction instance, bound to this dataset. """ kwargs['dataset'] = self return Transaction(*args, **kwargs)
def update_report(employee_id, report_id, rows, description): with Transaction(): report = _get_report(employee_id, report_id, False) if report is None: raise NoSuchReport() if report['status'] != 'pending': raise BadReportStatus(report['status']) _upsert_report(employee_id, report_id, rows) if description is not None: report['description'] = description report['updated'] = datetime.datetime.utcnow() datastore.put([report])
def get(keys, missing=None, deferred=None, connection=None): """Retrieves entities, along with their attributes. :type keys: list of :class:`gcloud.datastore.key.Key` :param keys: The keys to be retrieved from the datastore. :type missing: an empty list or None. :param missing: If a list is passed, the key-only entities 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 keys returned by the backend as "deferred" will be copied into it. Use only as a keyword param. :type connection: :class:`gcloud.datastore.connection.Connection` :param connection: Optional. The connection used to connect to datastore. :rtype: list of :class:`gcloud.datastore.entity.Entity` :returns: The requested entities. """ if not keys: return [] connection = _require_connection(connection) dataset_id = _get_dataset_id_from_keys(keys) transaction = Transaction.current() entity_pbs = connection.lookup( dataset_id=dataset_id, key_pbs=[k.to_protobuf() for k in keys], missing=missing, deferred=deferred, transaction_id=transaction and transaction.id, ) if missing is not None: missing[:] = [ helpers.entity_from_protobuf(missed_pb) for missed_pb in missing] if deferred is not None: deferred[:] = [ helpers.key_from_protobuf(deferred_pb) for deferred_pb in deferred] entities = [] for entity_pb in entity_pbs: entities.append(helpers.entity_from_protobuf(entity_pb)) return entities
def __init__(self, client, transaction_id='TRANSACTION'): from gcloud.datastore.transaction import Transaction self._client = client xact = self._transaction = Transaction(client) xact._id = transaction_id
def transaction(self, *args, **kwargs): from gcloud.datastore.transaction import Transaction kwargs['dataset'] = self return Transaction(*args, **kwargs)
def get_multi(keys, missing=None, deferred=None, connection=None, dataset_id=None): """Retrieves entities, along with their attributes. :type keys: list of :class:`gcloud.datastore.key.Key` :param keys: The keys to be retrieved from the datastore. :type missing: an empty list or None. :param missing: If a list is passed, the key-only entities 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 keys returned by the backend as "deferred" will be copied into it. Use only as a keyword param. :type connection: :class:`gcloud.datastore.connection.Connection` :param connection: Optional. The connection used to connect to datastore. If not passed, inferred from the environment. :type dataset_id: :class:`gcloud.datastore.connection.Connection` :param dataset_id: Optional. The dataset ID used to connect to datastore. If not passed, inferred from the environment. :rtype: list of :class:`gcloud.datastore.entity.Entity` :returns: The requested entities. :raises: EnvironmentError if ``connection`` or ``dataset_id`` not passed, and cannot be inferred from the environment. ValueError if one or more of ``keys`` has a dataset ID which does not match the passed / inferred dataset ID. """ if not keys: return [] connection = _require_connection(connection) dataset_id = _require_dataset_id(dataset_id, keys[0]) if list(set([key.dataset_id for key in keys])) != [dataset_id]: raise ValueError('Keys do not match dataset ID') transaction = Transaction.current() entity_pbs = _extended_lookup( connection, dataset_id=dataset_id, key_pbs=[k.to_protobuf() for k in keys], missing=missing, deferred=deferred, transaction_id=transaction and transaction.id, ) if missing is not None: missing[:] = [ helpers.entity_from_protobuf(missed_pb) for missed_pb in missing] if deferred is not None: deferred[:] = [ helpers.key_from_protobuf(deferred_pb) for deferred_pb in deferred] entities = [] for entity_pb in entity_pbs: entities.append(helpers.entity_from_protobuf(entity_pb)) return entities
def __init__(self, dataset_id, connection, transaction_id): from gcloud.datastore.transaction import Transaction xact = self._transaction = Transaction(dataset_id, connection) xact._id = transaction_id
def transaction(self): """Proxy to :class:`gcloud.datastore.transaction.Transaction`.""" return Transaction(self)
def get(keys, missing=None, deferred=None, connection=None, dataset_id=None): """Retrieves entities, along with their attributes. :type keys: list of :class:`gcloud.datastore.key.Key` :param keys: The keys to be retrieved from the datastore. :type missing: an empty list or None. :param missing: If a list is passed, the key-only entities 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 keys returned by the backend as "deferred" will be copied into it. Use only as a keyword param. :type connection: :class:`gcloud.datastore.connection.Connection` :param connection: Optional. The connection used to connect to datastore. If not passed, inferred from the environment. :type dataset_id: :class:`gcloud.datastore.connection.Connection` :param dataset_id: Optional. The dataset ID used to connect to datastore. If not passed, inferred from the environment. :rtype: list of :class:`gcloud.datastore.entity.Entity` :returns: The requested entities. :raises: EnvironmentError if ``connection`` or ``dataset_id`` not passed, and cannot be inferred from the environment. ValueError if one or more of ``keys`` has a dataset ID which does not match the passed / inferred dataset ID. """ if not keys: return [] connection = _require_connection(connection) dataset_id = _require_dataset_id(dataset_id, keys[0]) if list(set([key.dataset_id for key in keys])) != [dataset_id]: raise ValueError('Keys do not match dataset ID') transaction = Transaction.current() entity_pbs = _extended_lookup( connection, dataset_id=dataset_id, key_pbs=[k.to_protobuf() for k in keys], missing=missing, deferred=deferred, transaction_id=transaction and transaction.id, ) if missing is not None: missing[:] = [ helpers.entity_from_protobuf(missed_pb) for missed_pb in missing] if deferred is not None: deferred[:] = [ helpers.key_from_protobuf(deferred_pb) for deferred_pb in deferred] entities = [] for entity_pb in entity_pbs: entities.append(helpers.entity_from_protobuf(entity_pb)) return entities