简体   繁体   English

使用PyMongo和JSON(反)序列化

[英](De-)Serialization with PyMongo and JSON

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. 在一个将数据保留在MongoDB中并且还通过(只读)RESTish JSON API公开一些数据的项目中,处理Python对象需要一些额外的工作。 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: 因此,对于JSON序列化,我想到了:

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: 但是现在我想将foo插入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? 这如何工作?

By calling db.foobars.insert(foo) , you are trying to insert an instance of a Foo class. 通过调用db.foobars.insert(foo) ,您正在尝试插入Foo类的实例。 insert method allows only a dict, or a list of dicts as the first argument. insert方法仅允许一个字典或一个字典列表作为第一个参数。 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 文件“ /home/alexander/.virtualenvs/so/local/lib/python2.7/site-packages/pymongo/collection.py”,第351行,插入docs = [self .__ database._fix_incoming(doc,self)文档中的文档] TypeError:非序列迭代

One way to fix this is to load encoded string back into dict: 解决此问题的一种方法是将encoded字符串重新加载到dict中:

foo = Foo("bar")
encoded = json.dumps(foo, cls=Encoder)
db.foobars.insert(json.loads(encoded))

Or, use __dict__ : 或者,使用__dict__

db.foobars.insert(foo.__dict__)

Hope that helps. 希望能有所帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM