2011-09-27 16 views
6

Appengine'de, otomatik olarak hesaplanan ve nesne ile saklanan bir özellik değerine sahip olmaya çalışıyorum.Bir python uygulama motoru modelinde put() yönteminin üzerine yazmak nasıl?

Sınıfım var, Dikdörtgen ve genişliği, yüksekliği ve alanı var. Açıkçası alan genişlik ve yükseklik fonksiyonudur, ama bir özellik olmasını istiyorum çünkü onu sıralamak için kullanmak istiyorum. Yani şöyle Dikdörtgen depolarken bölgeyi gizlice koymak() işlevini değiştirmek için deneyin:

re1 = Rectangle(width=10, height=10) 
re1.put() 
print re1.area  # >> 10 

Ama ne zaman: Doğrudan Alan nesne üzerinde put() çağırdığınızda

class Rectangle(db.Model): 
    width = db.IntegerProperty() 
    height = db.IntegerProperty() 
    area = db.IntegerProperty() 

    def put(self, **kwargs): 
     self.area = self.width * self.height 
     super(Rectangle, self).put(**kwargs) 

Bu işleri db.put()'u kullanıyorum (örneğin bir çok şeyi bir kerede saklamak için), bu kırılmalar.

re2 = Rectangle(width=5, height=5) 
db.put(re2) 
print re2.area  # >> None 

Hesaplanan değerde 'gizlice girmenin uygun yolu nedir?

+0

Öğeyi veritabanından alırsanız ne alırsınız? hesaplanan alan nedir? – rocksportrocker

+0

Veri deposunu kontrol ettim ve aynı şeyi söylüyor; İlk dikdörtgenin “10” ve ikinci için “Yok”. – Paul

+1

Ben db.put() 'asla nesneler üzerinde bireysel' koymak() 'yöntemini çağırır' şüpheli - muhtemelen veritabanı özellikleri için onları inceler ve toplu insert ifadeleri yaratır. Eğer 'put' yerine '__init__' içinde bir alan belirlerseniz, ne olur? – larsks

cevap

7

Koymayı geçersiz kılmayın - gözlemlediğinizde, kırılgandır ve modelin yerine koyma işlevi yerine db.put'u çağırırsanız çağrı yapılmaz.

Neyse ki, App Engine gerçekten kolay kullanım senaryosunu yapan bir ComputedProperty sağlamaktadır:

class Rectangle(db.Model): 
    width = db.IntegerProperty() 
    height = db.IntegerProperty() 

    @db.ComputedProperty 
    def area(self): 
     return self.width * self.height 
+0

Teşekkürler, bu bir cazibe gibi çalışır! – Paul

1

Ben ComputedProperty açıklanan belirli bir senaryo için gitmek için yol olduğu konusunda hemfikirdir. Bununla birlikte, put işlevini aşırı yüklemek yararlı olabilir. Örneğin, veri yazımlarını yayınlayan tüm arayanların kaydını tutmak için aşağıdaki kodu kullanırız, böylelikle yazımlardaki ani hataları kolayca çözebiliriz.

from google.appengine.ext import db 

_orig_db_put_async = db.put_async 
_orig_db_model_put = db.Model.put 

def _new_db_put_async(models, *args, **kwargs): 
    """Instrumented version of db.put_async (which db.put also calls).""" 
    retval = _orig_db_put_async(models, *args, **kwargs) 
    msg = ['query: %s' % _get_caller()] 
    # 'models' can be either a single model instance, or a list of them. 
    try: 
     for model in models: 
      msg.append(model.__class__.__name__ + '.<db.put>') 
    except TypeError: 
     msg.append(models.__class__.__name__ + '.<db.put>') 
    instance_cache.increment(' -- '.join(msg)) 
    return retval 


def _new_db_model_put(self, *args, **kwargs): 
    """Like entity.put() but stores put-stats in the instance cache.""" 
    retval = _orig_db_model_put(self, *args, **kwargs) 
    msg = ['query: %s' % _get_caller()] 
    msg.append(self.__class__.__name__ + '.<put>') 
    instance_cache.increment(' -- '.join(msg)) 
    return retval 

Bu kod codepaths memcache önde gelen yazarlarını veren hangi sayımını tutar ve daha sonra ara sıra günlükleri bunu dışarı atar. Günlük hatları şöyle görünür: 3041 kaç kez

3041: activity_summary.py:312 -- UserData.<put>

activity_summary.py ait 312 bir UserData.put() yayınlanan çizgi.

İlgili konular