0

Good afternoon.

I'm trying to combine Python, MongoDB (via pymongo) and Flask to create client-server application. I want to use one of methods to return all the entire collection, like here:

@app.route('/entries', methods = ['GET'])
def get_entries():
    client = MongoClient(db_host, db_port)
    db_demo = client['demo_database']
    entries = db_demo.entries
    return JSONEncoder().encode(entries)

I also have an Encoder class, as advised here:

class JSONEncoder(json.JSONEncoder):
    def default(self, o):
        if isinstance(o, ObjectId):
            return str(o)
        return json.JSONEncoder.default(self, o)

Data collection is very simple - actually, only one item with few fields. What am I doing wrong? Perhaps I should develop more sophisticated encoder class?

Community
  • 1
  • 1
Rail Suleymanov
  • 361
  • 1
  • 4
  • 16
  • You are trying to encode a `MongoDB Collection` , send either a `Mongodb Cursor` or individual entries to your JSONEncoder function. – thegreenogre May 03 '15 at 17:12
  • @thegreenogre, that didn't help - now it says "TypeError: is not JSON serializable" (I used entries.find() now). – Rail Suleymanov May 03 '15 at 18:15
  • I am sorry, I didn't realize the author was traversing the cursor in the linked question. You have to send a document to your encoder method and not an object. If you want to return all the documents of your collection,traverse the cursor and store them locally and then return the array/list. – thegreenogre May 03 '15 at 19:18

2 Answers2

0

Use bson.json_util.dumps, which already supports all the MongoDB extended JSON types:

>>> from bson.json_util import dumps
>>> c.test.test.insert_many([{} for _ in range(3)])
<pymongo.results.InsertManyResult object at 0x7f6ed3189550>
>>> dumps(c.test.test.find())
'[{"_id": {"$oid": "554faa99fa5bd8782e1698cf"}}, {"_id": {"$oid": "554faa99fa5bd8782e1698d0"}}, {"_id": {"$oid": "554faa99fa5bd8782e1698d1"}}]'
Bernie Hackett
  • 8,749
  • 1
  • 27
  • 20
0

Using a combination of both approaches, I prefer the solution that I provided here

from flask import Flask
from flask.json import JSONEncoder

from bson import json_util

from . import resources

# define a custom encoder point to the json_util provided by pymongo (or its dependency bson)
class CustomJSONEncoder(JSONEncoder):
    def default(self, obj): return json_util.default(obj)

application = Flask(__name__)
application.json_encoder = CustomJSONEncoder

if __name__ == "__main__":
    application.run()
aitorhh
  • 2,331
  • 1
  • 23
  • 35