有没有办法直接在 mongoDB 中存储 python 对象而不序列化它们

Posted

技术标签:

【中文标题】有没有办法直接在 mongoDB 中存储 python 对象而不序列化它们【英文标题】:Is there a way to store python objects directly in mongoDB without serializing them 【发布时间】:2013-08-08 00:22:38 【问题描述】:

我在某处读到,您可以使用 BSON 将 python 对象(更具体地说是字典)作为二进制文件存储在 MongoDB 中。但是现在我找不到任何与此相关的文档。

有人知道这到底是怎么做到的吗?

【问题讨论】:

完全不清楚您要做什么,您尝试了什么,什么没有奏效。请编辑问题以包含这些有用的详细信息。 :) 如果您这样做是为了提高性能,this benchmark 可能会让您大吃一惊。 @thg435:感谢您的链接,对于 I/O 对我的项目性能更为关键的项目,我会牢记这一点! @thg435:对我来说主要的问题是我严重依赖numpy数据类型的序列化,python的json模块不支持这个 附带说明,使用 Pickle(如答案中所建议)可能会遇到一些问题:pyvideo.org/video/2566/pickles-are-for-delis-not-software。总之 - 代码的安全性+可维护性问题。 【参考方案1】:

看来您仍然需要使用pickle 模块进行序列化,该模块将创建字节并使用pickle 反序列化这些字节将直接提供python 对象。

另外,您可以将 pickled 对象直接存储到 Mongo 中。

import pickle as pkl
from uuid import uuid4

from pymongo import MongoClient

data = dict(key='mongo')
picked_data = pkl.dumps(data)
uid = uuid4()

client = MongoClient() # add DB url in the constructor if needed
db = client.test

# insertion
db.data.insert_one(
    'uuid': uid,
    'data': picked_data
)

# retrieval
result = db.data.find_one('uuid': uid)
assert pkl.loads(result['data']) == data

【讨论】:

【参考方案2】:

没有办法将对象存储在文件(数据库)中而不对其进行序列化。如果数据需要从一个进程移动到另一个进程或另一个服务器,则需要以某种形式将其序列化以进行传输。由于您询问的是 MongoDB,因此数据绝对会以某种形式序列化,以便存储在 MongoDB 数据库中。使用 MongoDB 时为BSON。

如果您实际上是在询问是否有办法在 MongoDB 文档中存储更原始形式的 Python 对象,您可以将 Binary 字段插入到可以包含您想要的任何数据的文档中喜欢。它不能以这种形式以任何方式直接查询,因此您可能会失去使用像 MongoDB 这样的 NoSQL 文档数据库的很多好处。

>>> from pymongo import MongoClient
>>> client = MongoClient('localhost', 27017)
>>> db = client['test-database']
>>> coll = db.test_collection    
>>> # the collection is ready now 
>>> from bson.binary import Binary
>>> import pickle
>>> # create a sample object
>>> myObj = 
>>> myObj['demo'] = 'Some demo data'
>>> # convert it to the raw bytes
>>> thebytes = pickle.dumps(myObj)
>>> coll.insert('bin-data': Binary(thebytes))

【讨论】:

感谢您的广泛回答!毕竟我想我会坚持使用pickle 序列化来构建一个JSON 对象。它为包含相同字符串的集合输出相同的字符串,这对我来说很重要。此外,我对数据库的 I/O 并不是我的代码中对性能最关键的部分。 示例代码中有一个错字:它应该在最后一行之前读取 pickle.dumps(myObj) 谢谢,pickle.dumps(obj) 为我工作 (scikit-learn.org/stable/modules/…) 我想应该更改答案,因为 pickle 现在已更改,应该是 pickle.dumps(obj) 而不是 pickle.dump(obj) 那么如果我们想再次从 Mongo 中读取数据需要进行哪些预处理呢?【参考方案3】:

假设您对 mongoDB 不是特别感兴趣,您可能不是在寻找 BSON。与 JSON 相比,BSON 只是一种不同的序列化格式,旨在提高速度和空间效率。另一方面,pickle 更多的是对 python 对象进行直接编码。

但是,在采用 pickle 之前进行速度测试,以确保它更适合您的用例。

【讨论】:

以上是关于有没有办法直接在 mongoDB 中存储 python 对象而不序列化它们的主要内容,如果未能解决你的问题,请参考以下文章

MongoDB 将Json数据直接写入MongoDB的方法

MongoDB Gridfs NODE 显示图片

有没有办法使用persistent-mongoDB中的低级mongoDB后端?

Node.js 监听 MongoDB 变化

在 MongoDB 中将枚举存储为字符串

Mongodb副本集存储回收