Pymongo BSON Binario guardar y recuperar?

Estoy trabajando en Python con MongoDB tratando de salvar una serie de flotadores con fuerza.

Puedo crear y almacenar correctamente *

pero NO PUEDO RECUPERAR LOS DATOS EN UN FORMATO UTILIZABLE.

>>> 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 "", line 1, in  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 "", line 1, in  UnicodeDecodeError: 'ascii' codec can't decode byte 0xb7 in position 0: ordinal not in range(128) >>> 

Una vez que recupere mi cadena de Python, puedo recuperar mi conjunto de flotadores aleatorios. ¿Pero cómo?

Vayamos a través de los errores:

  1. El primer error aparece simplemente porque necesita un objeto BSON real. Tenga en cuenta que nunca ha codificado ningún dato: crear bson.binary.Binary objeto bson.binary.Binary no significa invocar BSON.encode() .

  2. Y ahí es donde PyMongo te engaña un poco. El bson.binary.Binary es una instancia de str o bytes parcheada en tiempo de ejecución ( ver fuente ). Es por eso que obtiene el segundo error: lo que llama es en realidad str.decode() , no BSON.decode() . Entonces, gotfield contiene los datos flotantes aleatorios que has almacenado inicialmente, pero el objeto en sí tiene algunos métodos diferentes (por ejemplo, repr() ) vinculados a él.

Vengo ~ acabo de encontrar una manera. Espero que esto pueda ayudarte de alguna manera.

 from cStringIO import StringIO from PIL import Image 

guardar imagen:

 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 

recuperar imagen:

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

—-EDITAR—-

Si quieres devolver una imagen de los servidores web. Haz esto:

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

Utilice array.fromstring para la etapa de deencoding final. Puedo llegar al mismo lugar en el que estás:

 >>> from bson import Binary >>> import array >>> gotstring = Binary('\xb7\xc2?@\xd7\x1d\x81B5\x83\x01B\x13\x1f\xa4B', 5) 

Y finalmente:

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

Debe codificar la matriz antes de almacenarla, y no debe usar la array.tostring. Por favor, eche un vistazo a la documentación aquí .

 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'} 

BSON.decode (gotfield)

tiene un problema de TypeError, y debes escribirlo así abajo

BSON.decode (bson.BSON (gotfield))