31
  • I know this is a fairly common problem. I'm writing a small Flask app and I'm trying to feed some queries back to the view. I've connected to my local MongoDB setup, and made a successful query - but I can't generate a json object with it.

The most common solution I've seen is to import json_util from pymongo i.e.

import json
from pymongo import json_util

results = connection.get_collection('papayas_papaya')
results = results.find({
    'identifier': '1',
})
serialized_results = [json.dumps(result, default=json_util.default, separators=(',', ':')) for result in results]

I've installed pymongo into my Flask virtualenv using pip i.e :

pip install pymongo

When running the above code I keep getting the following error:

ImportError: cannot import name json_util

I can see this line in the pymongo-2.3-py2.6.egg-info/installed-files.txt ../bson/json_util.py

Anyone got any tips that can help me figure out what I'm doing wrong?

UPDATE: Having noodled about with this a little further - I've managed to get this working thus:

import pymongo
from bson.json_util import dumps

connection = pymongo.Connection("localhost", 27017)
db = connection.mydocs

def get():
    cursor = db.foo.find({"name" : "bar"})
    return dumps(cursor)

One of the problems I had was trying to pip install bson independently - pymongo brings bson with it and importing bson separately caused problems.

Thanks @Cagex for pointing me in the right direction

sunwukung
  • 2,815
  • 3
  • 41
  • 56
  • 3
    Never "pip install bson", that's someone else's obsolete module. Only "pip install pymongo" to get the official pymongo, bson, and gridfs modules. – A. Jesse Jiryu Davis May 30 '14 at 13:30

4 Answers4

16

It looks like you want to import from bson not pymongo. I believe json_util was moved to that module recently. https://pymongo.readthedocs.io/en/stable/api/bson/json_util.html

Brian Cajes
  • 3,274
  • 3
  • 21
  • 22
6

I've seen quite a few posts on this issue but they didn't resolve the issue for me. What worked for me was using dumps(), then loads():

import pymongo
from bson.json_util import dumps
from bson.json_util import loads
    
connection = pymongo.Connection("localhost", 27017)
db = connection.mydocs
    
def get():
    cursor = db.foo.find({"name" : "bar"})
    return loads(dumps(cursor))
mrazizi
  • 319
  • 2
  • 15
2

you can use list() to convert pymongo cursor to json object.

import pymongo
from bson.json_util import dumps
from bson.json_util import loads

connection = pymongo.Connection("localhost", 27017)
db = connection.mydocs

def get():
   cursor = list(db.foo.find({"name" : "bar"}))
   return loads(dumps(cursor))
Ananthu M
  • 77
  • 5
0

You first need define your own JSONEncoder:

import json
from datetime import datetime
from typing import Any

from bson import ObjectId


class MongoJSONEncoder(json.JSONEncoder):
    def default(self, o: Any) -> Any:
        if isinstance(o, ObjectId):
            return str(o)
        if isinstance(o, datetime):
            return str(o)
        return json.JSONEncoder.default(self, o)

And then use it to encode the Mongo cursor:

data_json = MongoJSONEncoder().encode(list(cursor))

that you can then load as a Python object with json.loads():

data_obj = json.loads(data_json)
Giorgos Myrianthous
  • 36,235
  • 20
  • 134
  • 156