2010-06-04 25 views
6

2 maneras posibles de persistencia de cadenas grandes en Google Datastore son Text y Blob tipos de datos.Google Datastore - Blob o texto

Desde una perspectiva de consumo de almacenamiento, ¿cuál de las 2 se recomienda? La misma pregunta desde una perspectiva de serialización y deserialización de protobuf.

Respuesta

4

No hay una diferencia de rendimiento significativa entre los dos, solo use la que mejor se adapte a sus datos. BlobProperty se debe usar para almacenar datos binarios (por ejemplo, objetos str) mientras que TextProperty se debe usar para almacenar cualquier dato textual (por ejemplo, objetos unicode o str). Tenga en cuenta que si almacena un str en un TextProperty, solo debe contener bytes ASCII (menos que el hex 80 o el decimal 128) (a diferencia de BlobProperty).

Ambas propiedades se derivan de UnindexedProperty como se puede ver en source.

Aquí es una aplicación de ejemplo que demuestra que no hay diferencia en la sobrecarga de almacenamiento para estos ASCII o UTF-8 cuerdas:

import struct 

from google.appengine.ext import db, webapp 
from google.appengine.ext.webapp.util import run_wsgi_app 

class TestB(db.Model): 
    v = db.BlobProperty(required=False) 

class TestT(db.Model): 
    v = db.TextProperty(required=False) 

class MainPage(webapp.RequestHandler): 
    def get(self): 
     self.response.headers['Content-Type'] = 'text/plain' 

     # try simple ASCII data and a bytestring with non-ASCII bytes 
     ascii_str = ''.join([struct.pack('>B', i) for i in xrange(128)]) 
     arbitrary_str = ''.join([struct.pack('>2B', 0xC2, 0x80+i) for i in xrange(64)]) 
     u = unicode(arbitrary_str, 'utf-8') 

     t = [TestT(v=ascii_str), TestT(v=ascii_str*1000), TestT(v=u*1000)] 
     b = [TestB(v=ascii_str), TestB(v=ascii_str*1000), TestB(v=arbitrary_str*1000)] 

     # demonstrate error cases 
     try: 
      err = TestT(v=arbitrary_str) 
      assert False, "should have caused an error: can't store non-ascii bytes in a Text" 
     except UnicodeDecodeError: 
      pass 
     try: 
      err = TestB(v=u) 
      assert False, "should have caused an error: can't store unicode in a Blob" 
     except db.BadValueError: 
      pass 

     # determine the serialized size of each model (note: no keys assigned) 
     fEncodedSz = lambda o : len(db.model_to_protobuf(o).Encode()) 
     sz_t = tuple([fEncodedSz(x) for x in t]) 
     sz_b = tuple([fEncodedSz(x) for x in b]) 

     # output the results 
     self.response.out.write("text: 1=>%dB 2=>%dB 3=>%dB\n" % sz_t) 
     self.response.out.write("blob: 1=>%dB 2=>%dB 3=>%dB\n" % sz_b) 

application = webapp.WSGIApplication([('/', MainPage)]) 
def main(): run_wsgi_app(application) 
if __name__ == '__main__': main() 

Y aquí está la salida:

text: 1=>172B 2=>128047B 3=>128047B 
blob: 1=>172B 2=>128047B 3=>128047B 
+2

No estaba' t consciente de que las propiedades de texto solo pueden contener bytes ASCII. Esa realización responde mi pregunta. Gracias. – Keyur

+1

Eso no es cierto, las propiedades de texto almacenan unicode. Pero si asigna una cadena de bytes ('raw') (escriba 'str') a una propiedad de texto, intentará convertir a unicode, que usa la codificación predeterminada del sistema, que es ASCII. Necesita decodificar cadenas explícitamente si desea hacer lo contrario. –

+0

Gracias Nick. Intenté decir que 'TextProperty' no puede almacenar objetos' str' que contengan bytes que no sean ASCII pero (como usted señaló) mi comentario no lo dejó claro así que lo eliminé. –

Cuestiones relacionadas