Python Pymongo BSON二进制文件保存和检索?

Python Pymongo BSON二进制文件保存和检索?,python,mongodb,pymongo,bson,Python,Mongodb,Pymongo,Bson,我在Python中使用MongoDB,试图保存一个浮点数组 我可以正确创建和存储* 但是我无法检索可用格式的数据。 >>> import random, array, pymongo >>> from bson.binary import Binary as BsonBinary >>> con = pymongo.Connection('localhost', 27017) >>> mm = con['testDataba

我在Python中使用MongoDB,试图保存一个浮点数组

我可以正确创建和存储*

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

>>> 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\xc2?@\xd7\x1d\x81B5\x83\x01B\x13\x1f\xa4B'
>>> vbson = BsonBinary(vstring, 5)
>>> vbson
Binary('\xb7\xc2?@\xd7\x1d\x81B5\x83\x01B\x13\x1f\xa4B', 5)
>>> doc1 = { 'something': 1 , 'else' : vbson}
>>> doc1
{'something': 1, 'else': Binary('\xb7\xc2?@\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\xc2?@\xd7\x1d\x81B5\x83\x01B\x13\x1f\xa4B', 5)}
>>> gotfield = gotdoc['else']
>>> gotfield
Binary('\xb7\xc2?@\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)
>>>
>导入随机、数组、pymongo
>>>从bson.binary将二进制文件导入为bson二进制文件
>>>con=pymongo.Connection('localhost',27017)
>>>mm=con['testDatabase']
>>>VAL=[random.random()*100代表范围(1,5)内的x]
>>>瓦尔斯
[2.9962593, 64.5582810776, 32.3781311717, 82.0606953423]
>>>varray=array.array('f',vals)
>>>瓦雷
数组('f',[2.9962593,64.5582810776,32.3781311717,82.0606953423])
>>>vstring=varray.tostring()
>>>vstring
“\xb7\xc2?@\xd7\x1d\x81B5\x83\x01B\x13\x1f\xa4B”
>>>vbson=BsonBinary(vstring,5)
>>>维布森
二进制('\xb7\xc2?@\xd7\x1d\x81B5\x83\x01B\x13\x1f\xa4B',5)
>>>doc1={'something':1,'else':vbson}
>>>文件1
{'something':1,'else':二进制('\xb7\xc2?@\xd7\x1d\x81B5\x83\x01B\x13\x1f\xa4B',5)}
>>>mm.test1.insert(doc1)
ObjectID('530f7af1d809d80d3db1f635')
>>>gotdoc=mm.test1.find_one()
>>>戈多克
{u''id':ObjectId('530f7af1d809d80d3db1f635'),u'something':3,u'else':二进制('\xb7\xc2?@\xd7\x1d\x81B5\x83\x01B\x13\x1f\xa4B',5)}
>>>gotfield=gotdoc['else']
>>>戈特菲尔德
二进制('\xb7\xc2?@\xd7\x1d\x81B5\x83\x01B\x13\x1f\xa4B',5)
>>>从bson导入bson
>>>BSON.decode(戈特菲尔德)
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
TypeError:必须使用BSON实例作为第一个参数调用未绑定的decode()方法(改为获取二进制实例)
>>>gotfield.decode()
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
UnicodeDecodeError:“ascii”编解码器无法解码位置0中的字节0xb7:序号不在范围内(128)
>>>

一旦我找回Python字符串,我就可以找回随机浮点数组。但是怎么做呢?

让我们看看错误:

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

  • 这就是PyMongo欺骗你的地方。
    bson.binary.binary
    是一个运行时修补的
    str
    bytes
    实例()。这就是为什么会出现第二个错误:您调用的实际上是
    str.decode()
    ,而不是
    BSON.decode()
    。因此,
    gotfield
    包含最初存储的随机浮点数据,但对象本身绑定了一些不同的方法(例如
    repr()


  • 您需要在存储数组之前对其进行编码,并且不应使用array.tostring。请看一下文档

    从bson导入bson
    bson_string=bson.encode({“hello”:“world”})
    >>>bson_字符串
    “\x16\x00\x00\x00\x02hello\x00\x06\x00\x00\x00\x00world\x00\x00”
    >>>bson_string.decode()
    {u'hello':u'world'}
    
    使用
    array.fromstring
    作为最终解码阶段。我可以到达你所在的同一地点,就像这样:

    >>> from bson import Binary
    >>> import array
    >>> gotstring = Binary('\xb7\xc2?@\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])
    
    BSON.decode(戈特菲尔德)

    它有一个TypeError问题,您应该这样写

    BSON.decode(BSON.BSON(gotfield))


    我来了~我只是想办法。希望这能对你有所帮助

    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
    

    我不需要数据结构的bson编码。我有一个有效编码和存储的二进制对象。我需要把它转换回我放进去的东西。因此,显然,BSON.encode/decode不是正确的方法。这是有道理的,但解决方法是什么?如何从bson.binary.binary返回原始数据类型?可以使用cPickle或类似的东西来完成吗?