Reiion
Reiion

Reputation: 943

Python-Pymongo : InvalidDocument on key <bson.ObjectId>

I am currently trying to build a query in a string then after that use eval (ast_eval) to transform it to a dict in order to pass up to pymongo update.

for item in default_properties:
    query = '{"_id": {ObjectId:"%s"}}' % (oid)
if (doc["diff_id"] == diff_id):
                default_val_pos = [line[0], line[1],line[2],line[3],line[4],line[5],line[6],line[7],line[8]]
                update_val = '{ "$set":{"properties.%s": default_val_pos[%d] } }' % (item,idx)
                db.routes.update(eval(query), eval(update_val))

I thought that it should be okay now since in mongoshell itself accepts the same query, the only difference is that I used from bson.objectid import ObjectId to format it well, however, this error occured:

InvalidDocument: documents must have only string keys, key was <class 'bson.objectid.ObjectId'>

As far as I see it, I don't have any "field key" that is not a string other than the ObjectId and hmmm I don't think the I should turn ObjectId in a hardcoded string lol. So I was wondering if someone can explain what's the problem?

Thanks!

Upvotes: 0

Views: 2500

Answers (1)

A. Jesse Jiryu Davis
A. Jesse Jiryu Davis

Reputation: 24009

It should just be:

query = '{"_id": ObjectId("%s")}' % (oid)

You're getting confused with MongoDB Extended JSON, which you can evaluate like:

query = '{"_id": {"$oid": "%s"}}' % (oid)
from bson import json_util
query_dict = json_util.loads(query)

But the simplest way to build your query is with Python literals:

query_dict = {"_id": ObjectId(oid)}

Upvotes: 2

Related Questions