tinydb icon indicating copy to clipboard operation
tinydb copied to clipboard

A simple implementation for update_multiple_by_id

Open abse4411 opened this issue 2 years ago • 0 comments

It seems that update_multiple() doesn't support updating data by the corresponding doc_id using QueryLike. So this is my simple implementation for it:

class MyTable(Table):
    def __init__(self, storage: Storage, name: str):
        super().__init__(storage, name)

    def update_multiple_by_id(
            self,
            updates: Iterable[
                Tuple[Union[Mapping, Callable[[Mapping], None]], int]
            ],
    ) -> List[int]:
        """
        Update all matching documents to have a given set of fields.

        :returns: a list containing the updated document's ID
        """

        # Define the function that will perform the update
        def perform_update(fields, table, doc_id):
            if callable(fields):
                # Update documents by calling the update function provided
                # by the user
                fields(table[doc_id])
            else:
                # Update documents by setting all fields from the provided
                # data
                table[doc_id].update(fields)

        # Perform the update operation for documents specified by a query

        # Collect affected doc_ids
        updated_ids = []

        def updater(table: dict):
            # We need to convert the keys iterator to a list because
            # we may remove entries from the ``table`` dict during
            # iteration and doing this without the list conversion would
            # result in an exception (RuntimeError: dictionary changed size
            # during iteration)
            for fields, doc_id in updates:
                if doc_id in table:
                    # Add ID to list of updated documents
                    updated_ids.append(doc_id)

                    # Perform the update (see above)
                    perform_update(fields, table, doc_id)

        # Perform the update operation (see _update_table for details)
        self._update_table(updater)

        return updated_ids

Then replace the TinyDB.table_class by the MyTable before creating a TinyDB instance.

TinyDB.table_class = MyTable

abse4411 avatar Jan 02 '24 14:01 abse4411