Search code examples
pythonmongodbpymongomongomock

mongomock BulkOperationBuilder.add_update() unexpected keyword argument 'sort'


I'm testing a function that performs a bulk upsert using UpdateOne with bulk_write. In production (using the real MongoDB client) everything works fine, but when running tests with mongomock I get this error:

app.mongodb.exceptions.CatalogException: failure in mongo repository function `batch_upsert_catalog_by_sku`: BulkOperationBuilder.add_update() got an unexpected keyword argument 'sort'

I don't pass any sort parameter in my code. Here's the relevant function:

def batch_upsert_catalog_by_sku(self, items: List[CatalogBySkuWrite]) -> None:
    operations = []
    current_time = datetime.datetime.now(datetime.timezone.utc)
    for item in items:
        update_fields = item.model_dump()
        update_fields["updated_at"] = current_time

        operations.append(
            UpdateOne(
                {"sku": item.sku, "chain_id": item.chain_id},
                {
                    "$set": update_fields,
                    "$setOnInsert": {"created_at": current_time},
                },
                upsert=True,
            )
        )

    if operations:
        result = self.collection.bulk_write(operations)
        logger.info("Batch upsert completed", 
                    matched=result.matched_count,
                    upserted=result.upserted_count,
                    modified=result.modified_count)

Has anyone seen this error with mongomock? Is it a version issue or a bug, and what would be a good workaround? I'm using mongomock version 4.3.0 and pymongo version 4.11.

Thanks!


Solution

  • This seem to be related to pymongo version 4.11.

    In 4.10.1, the method _add_to_bulk in the class UpdateOne here calls add_update this way:

        def _add_to_bulk(self, bulkobj: _AgnosticBulk) -> None:
            """Add this operation to the _AsyncBulk/_Bulk instance `bulkobj`."""
            bulkobj.add_update(
                self._filter,
                self._doc,
                False,
                bool(self._upsert),
                collation=validate_collation_or_none(self._collation),
                array_filters=self._array_filters,
                hint=self._hint,
            )
    

    However, in the current release (4.11), here, it calls it this way:

        def _add_to_bulk(self, bulkobj: _AgnosticBulk) -> None:
            """Add this operation to the _AsyncBulk/_Bulk instance `bulkobj`."""
            bulkobj.add_update(
                self._filter,
                self._doc,
                False,
                bool(self._upsert),
                collation=validate_collation_or_none(self._collation),
                array_filters=self._array_filters,
                hint=self._hint,
                sort=self._sort,
            )
    

    Latest version of mongomock does not seem to support the sort parameter, check here

    Forcing pymongo to version < 4.11 seem to solve the issue on my side (using Poetry: poetry add "pymongo<4.11")

    I have opened an issue in mongomock repository.