Reputation: 3500
In a project that keeps data inside a MongoDB and that also exposes some data via a (read-only) RESTish JSON API, dealing with Python objects requires some extra work. Serialization and Deserializing only works automatically when dealing with dicts or other simple types like string.
So for the JSON serialization, I came up with this:
import json
class Encoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, Foo):
return {'bar': obj.bar}
return json.JSONEncoder.fault(self, obj)
class Foo:
def __init__(self, bar):
self.bar = bar
foo = Foo("bar")
encoded = json.dumps(tokens, cls=Encoder)
This works pretty well. But now I would like to insert foo
into MongoDB:
db.foobars.insert(foo)
Obviously this doesn't work:
Traceback (most recent call last):
...
db.foobars.insert(foo)
File "/usr/local/lib/python2.7/dist-packages/pymongo/collection.py", line 351, in insert
docs = [self.__database._fix_incoming(doc, self) for doc in docs]
How can this made working?
Upvotes: 2
Views: 512
Reputation: 473863
By calling db.foobars.insert(foo)
, you are trying to insert an instance of a Foo
class. insert
method allows only a dict, or a list of dicts as the first argument. That's why you are seeing an error:
File "/home/alexander/.virtualenvs/so/local/lib/python2.7/site-packages/pymongo/collection.py", line 351, in insert docs = [self.__database._fix_incoming(doc, self) for doc in docs] TypeError: iteration over non-sequence
One way to fix this is to load encoded
string back into dict:
foo = Foo("bar")
encoded = json.dumps(foo, cls=Encoder)
db.foobars.insert(json.loads(encoded))
Or, use __dict__
:
db.foobars.insert(foo.__dict__)
Hope that helps.
Upvotes: 1