इसे और अधिक तेज़ी से करने का एक तरीका है अपने मॉडल को एक शब्दकोश में बदलना और अपने ev (de) serializers के रूप में मूल eval/repr फ़ंक्शन का उपयोग करना - निश्चित रूप से बुराई eval के साथ, लेकिन यह चाहिए यहां सुरक्षित रहें कि कोई बाहरी कदम नहीं है।
ठीक उसी तरह कार्यान्वित करने वाली कक्षा Fake_entity का एक उदाहरण नीचे। आप पहले अपना शब्दकोश fake = Fake_entity(entity)
के माध्यम से बनाते हैं, तो आप बस अपना डेटा memcache.set(key, fake.serialize())
के माध्यम से स्टोर कर सकते हैं। Serialize() repr के मूल शब्दकोश विधि के लिए एक साधारण कॉल है, यदि आपको आवश्यकता हो तो कुछ जोड़ों के साथ (उदाहरण के लिए स्ट्रिंग की शुरुआत में एक पहचानकर्ता जोड़ें)।
इसे वापस लाने के लिए, बस fake = Fake_entity(memcache.get(key))
का उपयोग करें। Fake_entity ऑब्जेक्ट एक साधारण शब्दकोश है जिसका कुंजी विशेषताओं के रूप में भी पहुंच योग्य है। संदर्भ को छोड़कर आप सामान्य रूप से अपनी इकाई गुणों तक पहुंच सकते हैं, ऑब्जेक्ट लाने के बजाए प्रॉपर्टीज कुंजी देते हैं (जो वास्तव में काफी उपयोगी है)। आप fake.get(), या अधिक रुचि के साथ वास्तविक इकाई भी प्राप्त कर सकते हैं, इसे बदल सकते हैं और फिर fake.put() के साथ सहेज सकते हैं।
यह सूचियों के साथ काम नहीं करता है (यदि आप किसी क्वेरी से कई इकाइयां प्राप्त करते हैं), लेकिन पहचानकर्ता का उपयोग करके आसानी से समायोजित किया जा सकता है जैसे '### मॉडल ENTITY ###' को विभाजक के रूप में । केवल db.Model के साथ प्रयोग करें, Expando के लिए छोटे समायोजन की आवश्यकता होगी।
class Fake_entity(dict):
def __init__(self, record):
# simple case: a string, we eval it to rebuild our fake entity
if isinstance(record, basestring):
import datetime # <----- put all relevant eval imports here
from google.appengine.api import datastore_types
self.update(eval(record)) # careful with external sources, eval is evil
return None
# serious case: we build the instance from the actual entity
for prop_name, prop_ref in record.__class__.properties().items():
self[prop_name] = prop_ref.get_value_for_datastore(record) # to avoid fetching entities
self['_cls'] = record.__class__.__module__ + '.' + record.__class__.__name__
try:
self['key'] = str(record.key())
except Exception: # the key may not exist if the entity has not been stored
pass
def __getattr__(self, k):
return self[k]
def __setattr__(self, k, v):
self[k] = v
def key(self):
from google.appengine.ext import db
return db.Key(self['key'])
def get(self):
from google.appengine.ext import db
return db.get(self['key'])
def put(self):
_cls = self.pop('_cls') # gets and removes the class name form the passed arguments
# import xxxxxxx ---> put your model imports here if necessary
Cls = eval(_cls) # make sure that your models declarations are in the scope here
real_entity = Cls(**self) # creates the entity
real_entity.put() # self explanatory
self['_cls'] = _cls # puts back the class name afterwards
return real_entity
def serialize(self):
return '### FAKE MODEL ENTITY ###\n' + repr(self)
# or simply repr, but I use the initial identifier to test and eval directly when getting from memcache
मैं इस पर गति परीक्षण का स्वागत करता हूं, मुझे लगता है कि यह अन्य दृष्टिकोणों की तुलना में काफी तेज़ है। इसके अलावा, यदि आपके मॉडल किसी भी तरह से बदल गए हैं तो आपके पास कोई जोखिम नहीं है।
धारावाहिक नकली इकाई कैसा दिखता है इसका एक उदाहरण नीचे।datetime (बनाया) पर एक विशेष देखो के साथ ही संदर्भ गुण (उप डोमेन) लें:
### वेबपेज ENTITY को ###
{ 'स्थिति': u'admin ',' session_expiry ': कोई नहीं,' first_name ': u'Louis', 'last_name': u'Le Sieur ',' modified_by ': कोई नहीं,' password_hash ': u'a9993e364706816aba3e25717000000000000000', 'भाषा': u'fr ',' बनाया गया ': datetime.datetime (2010, 7, 18, 21, 50, 11, 750000), 'संशोधित': कोई नहीं, 'बनाया_by': कोई नहीं, 'ईमेल': u'
[email protected] ',' key ':' agdqZXJlZ2xlcgwLEgVMb2dpbhjmAQw ',' session_ref ': कोई नहीं,' _cls ':' model.Login ',' groups ': [],' email___password_hash ': u'
[email protected]+a9993e364706816aba3e25717000000000000000', 'सबडोमेन': datastore_types.Key.from_path (u'ububdomain ' , 22 9 एल, _app = u'jeregle '),' अनुमति ': [],' अनुमतियां ': []}
व्यक्तिगत रूप से मैं छोटी अवधि में अपनी इकाइयों को कैश करने के लिए स्थैतिक चर (memcache से तेज़) का उपयोग करता हूं, और सर्वर को बदलते समय डेटास्टोर लाता है या इसकी याददाश्त किसी कारण से फ़्लश हो जाती है (जो वास्तव में अक्सर होता है) ।
मैंने अभी भी इसे वास्तव में बड़े और जटिल मॉडल के साथ भी आजमाया, लेकिन परिणाम इसके बारे में था। –
शायद GAE पर http://docs.python.org/library/timeit.html है? यह अधिक सटीक परिणाम दिखाना चाहिए, लेकिन फिर भी - आपके द्वारा लिंक किए गए ब्लॉग एंट्री को पढ़ने के बाद, मैं प्रोटोबफर्स और अचार के प्रदर्शन के बीच परिमाण अंतर का ऑर्डर करने की अपेक्षा करता हूं - और इसे समय-समय पर कैच किया जाना चाहिए। ( –
मैं जावा एपेंगेन का उपयोग करके, इसलिए मैं इस सिद्धांत का परीक्षण करने के लिए बहुत आलसी हूं - क्या अचार (कहीं) दृश्यों के पीछे परिणामों को कैशिंग कर रहा है, जबकि to_protobuf नहीं है? लेख के आधार पर, मुझे यकीन नहीं है कि मैं गति में परिमाण में वृद्धि के पूर्ण क्रम की अपेक्षा करता हूं, क्योंकि प्रोटेलफ संस्करण का उपयोग करके भी अचार को अभी भी बुलाया जा रहा है। इस्तेमाल की जाने वाली जगह निश्चित रूप से काफी छोटी हो सकती है। –