Ejemplo n.º 1
0
    def set(self, document_data, merge=False) -> Any:
        """Replace the current document in the Firestore database.

        A write ``option`` can be specified to indicate preconditions of
        the "set" operation. If no ``option`` is specified and this document
        doesn't exist yet, this method will create it.

        Overwrites all content for the document with the fields in
        ``document_data``. This method performs almost the same functionality
        as :meth:`create`. The only difference is that this method doesn't
        make any requirements on the existence of the document (unless
        ``option`` is used), whereas as :meth:`create` will fail if the
        document already exists.

        Args:
            document_data (dict): Property names and values to use for
                replacing a document.
            merge (Optional[bool] or Optional[List<apispec>]):
                If True, apply merging instead of overwriting the state
                of the document.

        Returns:
            :class:`~google.cloud.firestore_v1.types.WriteResult`:
            The write result corresponding to the committed document. A write
            result contains an ``update_time`` field.
        """
        batch = self._client.batch()
        batch.set(self, document_data, merge=merge)
        write_results = batch.commit()
        return _first_write_result(write_results)
Ejemplo n.º 2
0
    async def create(
        self,
        document_data: dict,
        retry: retries.Retry = gapic_v1.method.DEFAULT,
        timeout: float = None,
    ) -> write.WriteResult:
        """Create the current document in the Firestore database.

        Args:
            document_data (dict): Property names and values to use for
                creating a document.
            retry (google.api_core.retry.Retry): Designation of what errors, if any,
                should be retried.  Defaults to a system-specified policy.
            timeout (float): The timeout for this request.  Defaults to a
                system-specified value.

        Returns:
            :class:`~google.cloud.firestore_v1.types.WriteResult`:
                The write result corresponding to the committed document.
                A write result contains an ``update_time`` field.

        Raises:
            :class:`~google.cloud.exceptions.Conflict`:
                If the document already exists.
        """
        batch, kwargs = self._prep_create(document_data, retry, timeout)
        write_results = await batch.commit(**kwargs)
        return _first_write_result(write_results)
Ejemplo n.º 3
0
def test__first_write_result_more_than_one():
    from google.cloud.firestore_v1.types import write
    from google.cloud.firestore_v1.base_document import _first_write_result

    result1 = write.WriteResult()
    result2 = write.WriteResult()
    write_results = [result1, result2]
    result = _first_write_result(write_results)
    assert result is result1
Ejemplo n.º 4
0
def test__first_write_result_success():
    from google.protobuf import timestamp_pb2
    from google.cloud.firestore_v1.types import write
    from google.cloud.firestore_v1.base_document import _first_write_result

    single_result = write.WriteResult(update_time=timestamp_pb2.Timestamp(
        seconds=1368767504, nanos=458000123))
    write_results = [single_result]
    result = _first_write_result(write_results)
    assert result is single_result
Ejemplo n.º 5
0
    def create(self, document_data) -> Any:
        """Create the current document in the Firestore database.

        Args:
            document_data (dict): Property names and values to use for
                creating a document.

        Returns:
            :class:`~google.cloud.firestore_v1.types.WriteResult`:
                The write result corresponding to the committed document.
                A write result contains an ``update_time`` field.

        Raises:
            :class:`~google.cloud.exceptions.Conflict`:
                If the document already exists.
        """
        batch = self._client.batch()
        batch.create(self, document_data)
        write_results = batch.commit()
        return _first_write_result(write_results)
Ejemplo n.º 6
0
    async def set(
        self,
        document_data: dict,
        merge: bool = False,
        retry: retries.Retry = gapic_v1.method.DEFAULT,
        timeout: float = None,
    ) -> write.WriteResult:
        """Replace the current document in the Firestore database.

        A write ``option`` can be specified to indicate preconditions of
        the "set" operation. If no ``option`` is specified and this document
        doesn't exist yet, this method will create it.

        Overwrites all content for the document with the fields in
        ``document_data``. This method performs almost the same functionality
        as :meth:`create`. The only difference is that this method doesn't
        make any requirements on the existence of the document (unless
        ``option`` is used), whereas as :meth:`create` will fail if the
        document already exists.

        Args:
            document_data (dict): Property names and values to use for
                replacing a document.
            merge (Optional[bool] or Optional[List<apispec>]):
                If True, apply merging instead of overwriting the state
                of the document.
            retry (google.api_core.retry.Retry): Designation of what errors, if any,
                should be retried.  Defaults to a system-specified policy.
            timeout (float): The timeout for this request.  Defaults to a
                system-specified value.

        Returns:
            :class:`~google.cloud.firestore_v1.types.WriteResult`:
            The write result corresponding to the committed document. A write
            result contains an ``update_time`` field.
        """
        batch, kwargs = self._prep_set(document_data, merge, retry, timeout)
        write_results = await batch.commit(**kwargs)
        return _first_write_result(write_results)
Ejemplo n.º 7
0
    async def update(
        self,
        field_updates: dict,
        option: _helpers.WriteOption = None,
        retry: retries.Retry = gapic_v1.method.DEFAULT,
        timeout: float = None,
    ) -> write.WriteResult:
        """Update an existing document in the Firestore database.

        By default, this method verifies that the document exists on the
        server before making updates. A write ``option`` can be specified to
        override these preconditions.

        Each key in ``field_updates`` can either be a field name or a
        **field path** (For more information on **field paths**, see
        :meth:`~google.cloud.firestore_v1.client.Client.field_path`.) To
        illustrate this, consider a document with

        .. code-block:: python

           >>> snapshot = await document.get()
           >>> snapshot.to_dict()
           {
               'foo': {
                   'bar': 'baz',
               },
               'other': True,
           }

        stored on the server. If the field name is used in the update:

        .. code-block:: python

           >>> field_updates = {
           ...     'foo': {
           ...         'quux': 800,
           ...     },
           ... }
           >>> await document.update(field_updates)

        then all of ``foo`` will be overwritten on the server and the new
        value will be

        .. code-block:: python

           >>> snapshot = await document.get()
           >>> snapshot.to_dict()
           {
               'foo': {
                   'quux': 800,
               },
               'other': True,
           }

        On the other hand, if a ``.``-delimited **field path** is used in the
        update:

        .. code-block:: python

           >>> field_updates = {
           ...     'foo.quux': 800,
           ... }
           >>> await document.update(field_updates)

        then only ``foo.quux`` will be updated on the server and the
        field ``foo.bar`` will remain intact:

        .. code-block:: python

           >>> snapshot = await document.get()
           >>> snapshot.to_dict()
           {
               'foo': {
                   'bar': 'baz',
                   'quux': 800,
               },
               'other': True,
           }

        .. warning::

           A **field path** can only be used as a top-level key in
           ``field_updates``.

        To delete / remove a field from an existing document, use the
        :attr:`~google.cloud.firestore_v1.transforms.DELETE_FIELD` sentinel.
        So with the example above, sending

        .. code-block:: python

           >>> field_updates = {
           ...     'other': firestore.DELETE_FIELD,
           ... }
           >>> await document.update(field_updates)

        would update the value on the server to:

        .. code-block:: python

           >>> snapshot = await document.get()
           >>> snapshot.to_dict()
           {
               'foo': {
                   'bar': 'baz',
               },
           }

        To set a field to the current time on the server when the
        update is received, use the
        :attr:`~google.cloud.firestore_v1.transforms.SERVER_TIMESTAMP`
        sentinel.
        Sending

        .. code-block:: python

           >>> field_updates = {
           ...     'foo.now': firestore.SERVER_TIMESTAMP,
           ... }
           >>> await document.update(field_updates)

        would update the value on the server to:

        .. code-block:: python

           >>> snapshot = await document.get()
           >>> snapshot.to_dict()
           {
               'foo': {
                   'bar': 'baz',
                   'now': datetime.datetime(2012, ...),
               },
               'other': True,
           }

        Args:
            field_updates (dict): Field names or paths to update and values
                to update with.
            option (Optional[:class:`~google.cloud.firestore_v1.client.WriteOption`]):
                A write option to make assertions / preconditions on the server
                state of the document before applying changes.
            retry (google.api_core.retry.Retry): Designation of what errors, if any,
                should be retried.  Defaults to a system-specified policy.
            timeout (float): The timeout for this request.  Defaults to a
                system-specified value.

        Returns:
            :class:`~google.cloud.firestore_v1.types.WriteResult`:
            The write result corresponding to the updated document. A write
            result contains an ``update_time`` field.

        Raises:
            ~google.cloud.exceptions.NotFound: If the document does not exist.
        """
        batch, kwargs = self._prep_update(field_updates, option, retry,
                                          timeout)
        write_results = await batch.commit(**kwargs)
        return _first_write_result(write_results)
Ejemplo n.º 8
0
    def set(
        self,
        document_data: dict,
        merge: bool = False,
        retry: retries.Retry = gapic_v1.method.DEFAULT,
        timeout: float = None,
    ) -> write.WriteResult:
        """Create / replace / merge a document in the Firestore database.

        - To "upsert" a document (create if it doesn't exist, replace completely
          if it does), leave the ``merge`` argument at its default:

          >>> document_data = {"a": 1, "b": {"c": "Two"}}
          >>> document.get().to_dict() is None  # document exists
          False
          >>> document.set(document_data)
          >>> document.get().to_dict() == document_data  # exists
          True

        - To "merge" ``document_data`` with an existing document (creating if
          the document does not exist), pass ``merge`` as True``:

          >>> document_data = {"a": 1, "b": {"c": "Two"}}
          >>> document.get().to_dict() == {"d": "Three", "b": {}} # exists
          >>> document.set(document_data, merge=True)
          >>> document.get().to_dict() == {"a": 1, "d": "Three", "b": {"c": "Two"}}
          True

          In this case, existing documents with top-level keys which are
          not present in ``document_data`` (``"d"``) will preserve the values
          of those keys.


        - To merge only specific fields of ``document_data`` with existing
          documents (creating if the document does not exist), pass ``merge``
          as a list of field paths:


          >>> document_data = {"a": 1, "b": {"c": "Two"}}
          >>> document.get().to_dict() == {"b": {"c": "One", "d": "Four" }} # exists
          True
          >>> document.set(document_data, merge=["b.c"])
          >>> document.get().to_dict() == {"b": {"c": "Two", "d": "Four" }}
          True

          For more information on field paths, see
          :meth:`~google.cloud.firestore_v1.base_client.BaseClient.field_path`.

        Args:
            document_data (dict): Property names and values to use for
                replacing a document.
            merge (Optional[bool] or Optional[List<fieldpath>]):
                If True, apply merging instead of overwriting the state
                of the document.
            retry (google.api_core.retry.Retry): Designation of what errors, if any,
                should be retried.  Defaults to a system-specified policy.
            timeout (float): The timeout for this request.  Defaults to a
                system-specified value.

        Returns:
            :class:`~google.cloud.firestore_v1.types.WriteResult`:
            The write result corresponding to the committed document. A write
            result contains an ``update_time`` field.
        """
        batch, kwargs = self._prep_set(document_data, merge, retry, timeout)
        write_results = batch.commit(**kwargs)
        return _first_write_result(write_results)
Ejemplo n.º 9
0
    def _call_fut(write_results):
        from google.cloud.firestore_v1.base_document import _first_write_result

        return _first_write_result(write_results)
Ejemplo n.º 10
0
def test__first_write_result_failure_not_enough():
    from google.cloud.firestore_v1.base_document import _first_write_result

    write_results = []
    with pytest.raises(ValueError):
        _first_write_result(write_results)