2014-02-27 54 views
3

我正在Python中使用MongoDB尝试保存一个浮点数组。Pymongo BSON二进制保存和检索?

我可以创建并正确地存储*

我无法检索数据可用格式。

>>> import random, array, pymongo 
>>> from bson.binary import Binary as BsonBinary 
>>> con = pymongo.Connection('localhost', 27017) 
>>> mm = con['testDatabase'] 
>>> vals = [random.random() *100 for x in range(1, 5)] 
>>> vals 
[2.9962593, 64.5582810776, 32.3781311717, 82.0606953423] 
>>> varray = array.array('f', vals) 
>>> varray 
array('f', [2.9962593, 64.5582810776, 32.3781311717, 82.0606953423]) 
>>> vstring = varray.tostring() 
>>> vstring 
'\xb7\[email protected]\xd7\x1d\x81B5\x83\x01B\x13\x1f\xa4B' 
>>> vbson = BsonBinary(vstring, 5) 
>>> vbson 
Binary('\xb7\[email protected]\xd7\x1d\x81B5\x83\x01B\x13\x1f\xa4B', 5) 
>>> doc1 = { 'something': 1 , 'else' : vbson} 
>>> doc1 
{'something': 1, 'else': Binary('\xb7\[email protected]\xd7\x1d\x81B5\x83\x01B\x13\x1f\xa4B', 5)} 
>>> mm.test1.insert(doc1) 
ObjectID('530f7af1d809d80d3db1f635') 
>>> gotdoc = mm.test1.find_one() 
>>> gotdoc 
{u'_id': ObjectId('530f7af1d809d80d3db1f635'), u'something': 3, u'else': Binary('\xb7\[email protected]\xd7\x1d\x81B5\x83\x01B\x13\x1f\xa4B', 5)} 
>>> gotfield = gotdoc['else'] 
>>> gotfield 
Binary('\xb7\[email protected]\xd7\x1d\x81B5\x83\x01B\x13\x1f\xa4B', 5) 
>>> from bson import BSON 
>>> BSON.decode(gotfield) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: unbound method decode() must be called with BSON instance as first argument (got Binary instance instead) 
>>> gotfield.decode() 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
UnicodeDecodeError: 'ascii' codec can't decode byte 0xb7 in position 0: ordinal not in range(128) 
>>> 

一旦我得到我的Python字符串回来,我可以让我随意浮标阵列回来。但是如何?

回答

3

让我们通过错误:

  1. 的第一个错误出现,只是因为你需要一个实际的BSON对象。请注意,您从未编码过任何数据 - 创建对象并不意味着调用BSON.encode()

  2. 这就是PyMongo欺骗你一点。 bson.binary.Binary是运行时修补的strbytes实例(see source)。这就是为什么你会得到第二个错误:你所说的实际上是str.decode(),而不是BSON.decode()。因此,gotfield包含您最初存储的随机浮点数据,但对象本身有一些不同的方法(例如repr())绑定到它。

0

你需要在存放前,给数组编码,而不应使用与Array.toString。请查看文档here

from bson import BSON 
bson_string = BSON.encode({"hello": "world"}) 
>>> bson_string 
'\x16\x00\x00\x00\x02hello\x00\x06\x00\x00\x00world\x00\x00' 
>>> bson_string.decode() 
{u'hello': u'world'} 
+0

我不需要数据结构的bson编码。我有一个有效的编码和存储的二进制对象。我需要将它转换回我输入的相同的东西。显然,BSON.encode/decode不是正确的方法。 –

1

使用array.fromstring作为最终解码阶段。我能到你在像这样的相同点:

>>> from bson import Binary 
>>> import array 
>>> gotstring = Binary('\xb7\[email protected]\xd7\x1d\x81B5\x83\x01B\x13\x1f\xa4B', 5) 

最后:

>>> a = array.array('f') 
>>> a.fromstring(gotstring) 
>>> a 
array('f', [2.9962594509124756, 64.55828094482422, 32.37813186645508, 82.0606918334961]) 
0

BSON.decode(gotfield)

它有一个类型错误的问题,你应该把它写像下面

BSON.decode(bson.BSON(gotfield))

2

我来了〜我只是想办法。希望这可以帮助你以某种方式。

from cStringIO import StringIO 
from PIL import Image 

保存图像:

content = StringIO(f.read()) 

c = dict(
    content=bson.binary.Binary(content.getvalue()), 
) 
# insert dict into my database, sha1 is primary key 
image_data[sha1] = c 

检索图像:

f = image_data[sha1] 
image = Image.open(StringIO(f['content'])) 

---- ----编辑

如果你想返回从Web服务器的图像。像这样:

f = image_data[sha1] 
# f['mime'] is the type of image, for example 'png'. 
resp = Response(f['content'], mimetype='image/' + f['mime']) 
return resp