Search code examples
pythonmongodbodmbeanie

Bunnet/Beanie odm: replace_one with upsert


What would be the equivalent of .replace_one({"key": key}, doc, upsert=True) in bunnet/beanie odm?


Solution

  • The odm does not cover this functionality.

    It uses motor under the hood, and passes only the filter, the document, and the session downstream: https://github.com/roman-right/beanie/blob/e2d95be0843375353d6ec79a230f63d4f874ee0e/beanie/odm/queries/find.py#L948

            result: UpdateResult = (
                self.document_model.get_motor_collection().replace_one(
                    self.get_filter_query(),
                    get_dict(
                        document,
                        to_db=True,
                        exclude={"_id"},
                        keep_nulls=document.get_settings().keep_nulls,
                    ),
                    session=self.session,
                )
            )
    

    You can try to work it around wrapping it in a bulk write. When bulk_writer parameter is passed to update_one it seems to proxy arbitrary parameters pymongo_kwargs downstream: https://github.com/roman-right/beanie/blob/e2d95be0843375353d6ec79a230f63d4f874ee0e/beanie/odm/queries/find.py#L980

            bulk_writer.add_operation(
                Operation(
                    operation=ReplaceOne,
                    first_query=self.get_filter_query(),
                    second_query=get_dict(
                        document,
                        to_db=True,
                        exclude={"_id"},
                        keep_nulls=document.get_settings().keep_nulls,
                    ),
                    object_class=self.document_model,
                    pymongo_kwargs=self.pymongo_kwargs,
                )
            )
    

    but I would rather raised an issue or a PR to the maintainer, if I wanted to use the library, and not to fight against it.