PyMongo upsert throws "upsert must be an instance of bool" error

PythonMongodbPymongo

Python Problem Overview


I'm running an update on my MongoDB from Python. I have this line:

self.word_counts[source].update({'date':posttime},{"$inc" : words},{'upsert':True})

But it throws this error:

raise TypeError("upsert must be an instance of bool")

But True looks like an instance of bool to me!

How should I correctly write this update?

Python Solutions


Solution 1 - Python

The third argument to PyMongo's update() is upsert and must be passed a boolean, not a dictionary. Change your code to:

self.word_counts[source].update({'date':posttime}, {"$inc" : words}, True)

Or pass upsert=True as a keyword argument:

self.word_counts[source].update({'date':posttime}, {"$inc" : words}, upsert=True)

Your mistake was likely caused by reading about update() in the MongoDB docs. The JavaScript version of update takes an object as its third argument containing optional parameters like upsert and multi. But since Python allows passing keyword arguments to a function (unlike JavaScript which only has positional arguments), this is unnecessary and PyMongo takes these options as optional function parameters instead.

Solution 2 - Python

According to http://api.mongodb.org/python/2.3/api/pymongo/collection.html#pymongo.collection.Collection.update you should indeed pass upsert as a keyword rather than just True, that is

self.word_counts[source].update({'date':posttime},{"$inc" : words},**{'upsert':True})

Or

self.word_counts[source].update({'date':posttime},{"$inc" : words},upsert=True)

is a better approach than just passing True as if you ever wish to pass other kwargs such as safe or multi code might break if order of args is not kept.

Solution 3 - Python

upsert should be passed as either positional parameter, like so

self.word_counts[source].update(
    {'date':posttime},
    {"$inc" : words},
    True)

or as a keyword argument, like so

self.word_counts[source].update(
    {'date':posttime},
    {"$inc" : words},
    upsert=True)

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionComputationalSocialScienceView Question on Stackoverflow
Solution 1 - PythonBrendan W. McAdamsView Answer on Stackoverflow
Solution 2 - PythonTzury Bar YochayView Answer on Stackoverflow
Solution 3 - PythonRamashish BaranwalView Answer on Stackoverflow