Uploaded image for project: 'Python Driver'
  1. Python Driver
  2. PYTHON-4786

UpdateResult.did_upsert raises a TypeError

    • Type: Icon: Bug Bug
    • Resolution: Fixed
    • Priority: Icon: Unknown Unknown
    • 4.9.2, 4.10.1
    • Affects Version/s: 4.9
    • Component/s: None
    • None
    • Python Drivers
    • Not Needed
    • Hide

      1. What would you like to communicate to the user about this feature?
      2. Would you like the user to see examples of the syntax and/or executable code and its output?
      3. Which versions of the driver/connector does this apply to?

      Show
      1. What would you like to communicate to the user about this feature? 2. Would you like the user to see examples of the syntax and/or executable code and its output? 3. Which versions of the driver/connector does this apply to?

      In PYTHON-4550, we accidentally added this API to UpdateResult:

      class UpdateResult(_WriteResult):
      ...
          @property
          def did_upsert(self) -> bool:
              """Whether or not an upsert took place."""
              assert self.__raw_result is not None
              return len(self.__raw_result.get("upserted", {})) > 0
      

      did_upsert is unnessecary because an app can already check for an upsert like this: res.upserted_id is not None

      I'm also suspicious of the in_client_bulk flag that was added to UpdateResult and any logic that depends on it.

      Originally reported here: https://www.mongodb.com/community/forums/t/pymongo-bug-updateresult-did-upsert-throws/298787/1

      I'm using pymongo 4.9.1 with a local, docker-deployed atlas install of MongoDB 7.0.12.

      MRE:

      from pymongo import MongoClient
      
      mc = MongoClient(directConnection=True)
      
      # Record to be upserted just needs to not already exist
      update_result = mc.mydatabase.mycollection.update_one(
          {"hi": 55, "ok": 10},
          {"$set": {"well": 55}},
          upsert=True,
      )
      

      update_result.did_upsert
      Evaluating did_upsert throws because:

      python3.10/site-packages/pymongo/results.py", line 176, in did_upsert
            return len(self.__raw_result.get("upserted", {})) > 0
        TypeError: object of type 'ObjectId' has no len()
      As the error implies, self.__raw_result["upserted"] is a bson.objectid.ObjectId.
      

      Seems like a very straightforward bug to me. Let me know if you need any more information.

            Assignee:
            noah.stapp@mongodb.com Noah Stapp
            Reporter:
            shane.harvey@mongodb.com Shane Harvey
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: