Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
332 views
in Technique[技术] by (71.8m points)

python - Pymongo BSON Binary save and retrieve?

I'm working in Python with MongoDB trying to save an array of floats tightly.

I can Create and store correctly *

but I CANNOT RETRIEVE THE DATA IN A USABLE FORMAT.

>>> 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
'xb7xc2?@xd7x1dx81B5x83x01Bx13x1fxa4B'
>>> vbson = BsonBinary(vstring, 5)
>>> vbson
Binary('xb7xc2?@xd7x1dx81B5x83x01Bx13x1fxa4B', 5)
>>> doc1 = { 'something': 1 , 'else' : vbson}
>>> doc1
{'something': 1, 'else': Binary('xb7xc2?@xd7x1dx81B5x83x01Bx13x1fxa4B', 5)}
>>> mm.test1.insert(doc1)
ObjectID('530f7af1d809d80d3db1f635')
>>> gotdoc = mm.test1.find_one()
>>> gotdoc
{u'_id': ObjectId('530f7af1d809d80d3db1f635'), u'something': 3, u'else': Binary('xb7xc2?@xd7x1dx81B5x83x01Bx13x1fxa4B', 5)}
>>> gotfield = gotdoc['else']
>>> gotfield
Binary('xb7xc2?@xd7x1dx81B5x83x01Bx13x1fxa4B', 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)
>>>

Once I get my Python string back, I can get my array of random floats back. But how?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Let's go through the errors:

  1. The first error appears simply because you need an actual BSON object. Note, that you have never encoded any data - creating bson.binary.Binary object does not mean invoking BSON.encode().

  2. And that is where PyMongo cheats you a bit. The bson.binary.Binary is a runtime-patched str or bytes instance (see source). That is why you get the second error: what you call is actually str.decode(), not BSON.decode(). So, gotfield contains the random float data you've stored initially, but the object itself has some different methods (e.g. repr()) bound to it.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...