Не существует существенной разницы в производительности между двумя - используйте только то, что лучше всего подходит для ваших данных. 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
я не был» t известно, что свойства Text могут содержать только ASCII-байты. Это осознание отвечает на мой вопрос. Благодарю. – Keyur
Это не так - текстовые свойства сохраняют unicode. Но если вы присвоите строковое значение байта ('raw') (type 'str') для свойства text, оно попытается применить к unicode, который использует кодировку по умолчанию, которая является ASCII. Вы должны явно декодировать строки, если хотите сделать иначе. –
Спасибо, Ник. Я пытался сказать, что 'TextProperty' не может хранить объекты' str', которые содержат байты без ASCII, но (как вы указали) мой комментарий не сделал этого ясно, поэтому я удалил его. –