【问题标题】:How to serialize umongo documents如何序列化 umongo 文档
【发布时间】:2019-07-01 09:24:05
【问题描述】:

假设我有以下示例:

from datetime import datetime
import dill
from pymongo import MongoClient
from umongo import Instance, Document, fields, validate

db = MongoClient().test
instance = Instance(db)

@instance.register
class User(Document):
    email = fields.EmailField(required=True, unique=True)
    birthday = fields.DateTimeField(validate=validate.Range(min=datetime(1900, 1, 1)))
    friends = fields.ListField(fields.ReferenceField("User"))

    class Meta:
        collection = db.user

User.ensure_indexes()

goku = User(email='goku@sayen.com', birthday=datetime(1984, 11, 20))
goku.commit()

found_goku = User.find_one({"email": 'goku@sayen.com'})
with open("dumped.dil", "wb") as out_file:
    dill.dump(found_goku, out_file)

这会导致dill.dump 出现以下错误:

_pickle.PicklingError: Can't pickle <Implementation class 'tests.test_serialize_umongo.User'>: it's not found as tests.test_serialize_umongo.User

我知道我不能简单地腌制用户,因为我无法腌制数据库实例。我想使用 umongo 的 dump 和覆盖 __getstate__ 将用户腌制到字典,但我不知道如何解决这个 it's not found aserror。

【问题讨论】:

  • 你能发布完整的堆栈跟踪吗?您是否正在运行该确切样本以生成确切错误?我得到的结果与你不同。

标签: python serialization pickle umongo


【解决方案1】:

如果我理解正确,我相信您正在寻找以下内容。本质上,我们使用文档自己的dump() 方法将序列化的文档作为要腌制的用户传递。这里唯一的区别是最后一行:dill.dump(found_goku.dump(), out_file):

from datetime import datetime
import dill
from pymongo import MongoClient
from umongo import Instance, Document, fields, validate

db = MongoClient().test
instance = Instance(db)

@instance.register
class User(Document):
    email = fields.EmailField(required=True, unique=True)
    birthday = fields.DateTimeField(validate=validate.Range(min=datetime(1900, 1, 1)))
    friends = fields.ListField(fields.ReferenceField("User"))

    class Meta:
        collection = db.user

User.ensure_indexes()

goku = User(email='goku@sayen.com', birthday=datetime(1984, 11, 20))
goku.commit()

found_goku = User.find_one({"email": 'goku@sayen.com'})
with open("dumped.dil", "wb") as out_file:
    dill.dump(found_goku.dump(), out_file)

【讨论】:

  • 感谢这个简单的解决方案!您能否补充说您只需要在序列化之前调用转储?否则在查看代码块时可能不清楚您添加了什么。
猜你喜欢
  • 1970-01-01
  • 2020-06-16
  • 2019-04-26
  • 1970-01-01
  • 1970-01-01
  • 2016-02-14
  • 1970-01-01
  • 2016-01-22
相关资源
最近更新 更多