2010-06-04 30 views
6

2 cách có thể bền bỉ các chuỗi lớn trong Google Datastore là TextBlob loại dữ liệu.Google Datastore - Blob hoặc Văn bản

Từ góc độ tiêu thụ bộ nhớ, đề xuất nào trong số 2 được khuyến nghị? Cùng một câu hỏi từ một protobuf serialization và deserialization perspective.

Trả lời

4

Không có sự khác biệt về hiệu suất đáng kể giữa hai ứng dụng - chỉ cần sử dụng tùy chọn nào phù hợp nhất với dữ liệu của bạn. BlobProperty nên được sử dụng để lưu trữ dữ liệu nhị phân (ví dụ: đối tượng str) trong khi TextProperty nên được sử dụng để lưu trữ bất kỳ dữ liệu văn bản nào (ví dụ: unicode hoặc str đối tượng). Lưu ý rằng nếu bạn lưu trữ một str trong một TextProperty, thì chỉ được chứa các byte ASCII (nhỏ hơn hex 80 hoặc số thập phân 128) (không giống như BlobProperty).

Cả hai thuộc tính này đều có nguồn gốc từ UnindexedProperty như bạn có thể thấy trong số source.

Đây là một ứng dụng mẫu đó chứng tỏ rằng không có sự khác biệt trong chi phí lưu trữ cho những ASCII hoặc UTF 8-strings:

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

Và đây là kết quả:

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

Tôi wasn' t biết rằng các thuộc tính Text chỉ có thể chứa các byte ASCII. Nhận thức đó trả lời câu hỏi của tôi. Cảm ơn. – Keyur

+1

Điều đó không đúng - các thuộc tính văn bản lưu trữ unicode. Nhưng nếu bạn gán một chuỗi byte ('thô') (loại 'str') cho thuộc tính văn bản, nó sẽ cố gắng truyền sang unicode, sử dụng mã hóa mặc định của hệ thống, là ASCII. Bạn cần phải giải mã một cách rõ ràng nếu bạn muốn làm khác. –

+0

Cảm ơn Nick. Tôi đã cố gắng để nói rằng 'TextProperty' không thể lưu trữ' str' đối tượng có chứa byte không ASCII nhưng (như bạn chỉ ra) bình luận của tôi đã không làm cho rõ ràng vì vậy tôi đã xóa nó. –

Các vấn đề liên quan