Nie ma znaczącej różnicy w wydajności między tymi dwoma - wystarczy użyć tego, który najlepiej pasuje do danych. BlobProperty
należy używać do przechowywania danych binarnych (np. Obiektów str), a do przechowywania jakichkolwiek danych tekstowych (np. Obiektów unicode
lub str
) należy użyć kodu TextProperty
. Zauważ, że jeśli przechowujesz str
w TextProperty
, musi zawierać tylko bajty ASCII (mniej niż 80 lub 128) (w przeciwieństwie do BlobProperty
).
Obie te właściwości pochodzą z UnindexedProperty
, jak widać w source.
Tutaj jest app próbki, które pokazuje, że nie ma różnicy w obciążeniu pamięci dla tych ASCII lub UTF-8 ciągi:
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()
I tu jest wyjście:
text: 1=>172B 2=>128047B 3=>128047B
blob: 1=>172B 2=>128047B 3=>128047B
Nie byłem” t świadomy, że właściwości tekstu mogą zawierać tylko bajty ASCII. Ta realizacja odpowiada na moje pytanie. Dzięki. – Keyur
To nie jest prawda - właściwości tekstu przechowują kod Unicode. Ale jeśli przypiszesz ciąg bajtowy ("raw") (typ "str") do właściwości text, spróbuje on przesłać do Unicode, który używa domyślnego kodowania systemowego, czyli ASCII. Jeśli chcesz inaczej, musisz jawnie dekodować ciągi. –
Dzięki Nick. Próbowałem powiedzieć, że 'TextProperty' nie może przechowywać obiektów' str', które zawierają bajty inne niż ASCII, ale (jak zauważyłeś) mój komentarz nie wyjaśnił tak, więc usunąłem go. –