0

我有一個基於GAE的項目,使用dbDatastore。在我的項目中,我每15分鐘運行一次作業,並更新Datastore中的數據。然後我有一個端點查詢Datastore並顯示結果。但是,我得到的結果是陳舊的,而不是更新的結果。看來GAE沒有打到Datastore並從緩存中返回數據,但我不確定。這裏是我的代碼:Google App Engine數據存儲查詢返回陳舊數據

class MainHandler(webapp2.RequestHandler): 

    def get(self): 
     query = Contests.all() 
     contests_data = query.fetch(1) # fetch the data from datastore 
     self.response.write(contests_data[0].data) 

class DataBaseHandler(webapp2.RequestHandler): 

    # the job that runs every 15 minutes 
    def get(self): 
     contests_data = get_all_contests() # get the new data 
     query = Contests.all() 
     contests = query.fetch(1) 
     contests[1].data = contests_data # update the data 
     db.put(contests[0]) 
     self.response.write(json.dumps({"message":"updated"})) 

這裏是我的模型:

class Contests(db.Model): 
    """Models Contests""" 
    data = db.TextProperty(default="{}") 
    created = db.DateTimeProperty(auto_now_add=True) 
    modified = db.DateTimeProperty(auto_now=True) 

我嘗試使用memcache.flush_all()但即使是不解決問題的清除緩存。爲什麼GAE不返回更新的數據?我該如何解決這個問題?

編輯:我改變了查詢祖先查詢,但數據仍舊陳舊(和它是天)。

main.py

class MainHandler(webapp2.RequestHandler): 

     def get(self): 
      contest_list = ContestList.get_or_insert('contest_list', name='ContestList') 
      query = Contests.all() 
      query.ancestor(contest_list) 
      contests = query.fetch(1) 
      self.response.write(contests[0].data) 

    class DataBaseHandler(webapp2.RequestHandler): 

     def get(self): 
      contests_data = get_all_contests() 
      contest_list = ContestList.get_or_insert('contest_list', name='ContestList') 
      query = Contests.all() 
      query.ancestor(contest_list) 
      contests = query.fetch(1) 
      contests[0].data = contests_data 
      contests[0].put() 
      self.response.write(json.dumps({"message":"updated"})) 

models.py

class ContestList(db.Model): 
    name = db.StringProperty() 

class Contests(db.Model): 
    """Models Contests""" 
    data = db.TextProperty(default="{}") 
    created = db.DateTimeProperty(auto_now_add=True) 
    modified = db.DateTimeProperty(auto_now=True) 

我甚至嘗試使用key獲取數據:

class MainHandler(webapp2.RequestHandler): 

    def get(self): 
     q = ndb.Key('Contests', 'contest_data').get() 
     if q: 
      self.response.write(q.data) 
     else: 
      self.response.write("error") 

class DataBaseHandler(webapp2.RequestHandler): 

    def get(self): 
     Contests(key=ndb.Key('Contests', "contest_data"), data=get_all_contests()).put() 
     self.response.write(json.dumps({"message":"updated"})) 

什麼不打GAE數據存儲?我在這裏錯過了什麼?

+1

Patrice的回答是正確的 - 舊的crufty'db'並不會透明地爲你緩存,你需要新的偉大的'ndb'(當然,通過使用自定義上下文來控制),所以遇到的問題'db'不能由於緩存,必須與最終一致性相關, – 2015-02-07 19:31:49

+0

最終一致性需要1-2秒才能解決。如果您的數據超出了「陳舊」,那麼您的代碼中就有一個問題。 – 2015-02-07 19:35:34

+1

@AndreiVolgin,第二個或通常更少是* typical *,但沒有保證最壞情況延遲的上限。現代子系統(如ndb)的用戶幾乎從未觀察到,因爲memcache **具有強烈的一致性(雖然是volatile) - 但是對於舊的crufty db來說更加突出,反正「幾乎沒有」與「never」一樣: - )... – 2015-02-07 19:47:31

回答

4

數據存儲區最終只對查詢一致。在數據複製過程中,確實存在一種可能性,那就是您打到「陳舊」的數據。

爲了確保您在查詢中強制保持一致性,您需要使用祖先查詢或get by鍵。

瞭解更多關於這個here

例:祖先查詢

documentation)爲了做到這一點,你顯然需要改變你的結構位。我不知道什麼可能是模型「競賽」的祖先,但我們假設他們都屬於「主祖先」實體。

當您創建實體,你需要有一個類似於:

query = Contests.all() 
query.ancestor(mainAncestor) 
contests = query.fetch(1) 

這將迫使強:

newContest = Contest(parent=mainAncestor) 

然後,當您檢索,您在代碼中添加此數據的一致性。您顯然需要創建該「mainAncestor」,然後它會導致您需要確保解決的其他警告(例如,您只能每秒鐘向實體組(在同一祖先下編組的實體)寫入一次),例如)。

+2

很好的答案,但要使它很棒我有兩個建議:(一)你也可以直接鏈接到https://cloud.google.com/developers/articles/balancing-strong-and-eventual-consistency-with-google-雲數據存儲/(不需要通過那個以Java爲核心的SO Q :-)來發送OP,而且(B)理想地提供了一個簡單的Python例子,說明如何在OP的用例中人爲地使用祖先查詢...我upvoted無論如何,但建議你豐富答案!) – 2015-02-07 19:43:34

+0

公平點。對於A)來說,這實際上是我打算使用的鏈接。我應該仔細檢查。我會糾正這一點,並簡單地添加B :)。感謝您的建議 – Patrice 2015-02-07 19:46:54

+0

@Patrice @AlexMartelli非常感謝您的幫助!但即使在添加祖先查詢並試圖通過'key'獲取數據之後,它也不起作用。我已經編輯了更多細節的問題。 – 2015-02-09 07:11:29

相關問題