Google Datastore - Blob или Text - PullRequest
       5

Google Datastore - Blob или Text

6 голосов
/ 05 июня 2010

2 возможных способа сохранения больших строк в хранилище данных Google: Text и Blob типы данных.

С точки зрения использования хранилища, какой из 2 рекомендуется?Тот же вопрос с точки зрения сериализации и десериализации protobuf. * ​​1005 *

1 Ответ

4 голосов
/ 05 июня 2010

Между этими двумя показателями нет существенной разницы в производительности - просто используйте тот, который лучше всего подходит для ваших данных. BlobProperty следует использовать для хранения двоичных данных (например, объекты str), а TextProperty следует использовать для хранения любых текстовых данных (например, unicode или str объекты). Обратите внимание, что если вы храните str в TextProperty, он должен содержать только байты ASCII (меньше шестнадцатеричного 80 или десятичного 128) (в отличие от BlobProperty).

Оба эти свойства получены из UnindexedProperty, как вы можете видеть в source .

Вот пример приложения, которое демонстрирует, что нет разницы в затратах на хранение для этих строк ASCII или UTF-8:

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()

А вот и вывод:

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