1

我想在memcache中緩存查詢以加快閱讀速度。爲此,我需要一些爲查詢創建一些id的函數。如何緩存Google App Engine查詢 - 如何獲取查詢字符串/散列表和受影響的表?

class DeleteMe(db.Model) 
    pass 

query = DeleteMe.all() 

# how to get query string/hash form query? 
# how to get kind name from query? 

我想要做這樣的事情(getQueryKey是函數總是給出相同的查詢相同的值):

memcache.set(getQueryKey(query), list(query)) 

請幫我也可以是數據庫或NDB。

回答

1

這沒有什麼意義。查詢並不值得高速緩存:它只是一個無狀態的對象,很容易在一行代碼中重新創建。緩存適用於實際數據,從數據存儲中獲取費用很高。

如果您需要輕鬆引用一系列查詢,則可以將這些查詢簡單地存儲在字典中,無論是在模塊級還是作爲相關模型的類屬性,一個更好的解決方案。

+0

更仔細地閱讀的問題 - 他要求的方式通過散列/連載查詢本身獲得一個合適的標識符查詢的結果,這並非如此不合理。 – Greg

+0

更仔細地閱讀問題 - 它與緩存查詢結果不相關。 – Chameleon

4

有類似的問題;這裏是我的代碼:

def keyFromQuery(query): 
      """ 
        Derives a unique Key from a given query. 
        This Key is stable regardless in which order the filter have been applied 
        @param query: Query to derive key from 
        @type query: DB.Query 
        @returns: string 
      """ 
      origFilter = [ (x, y) for x, y in query._get_query().items() ] 
      for k, v in query._Query__orderings: 
        origFilter.append(("__%s ="%k, v)) 
      origFilter.append(("____kind", query._model_class().kind())) 
      origFilter.sort(key=lambda x: x[0]) 
      filterKey = "".join(["%s%s" % (x, y) for x, y in origFilter ]) 
      return(sha256(filterKey).hexdigest()) 
+0

感謝提示,但此代碼是非常危險的生產。 __x被破壞而不能以任何理由被訪問,_x不公開,所以最好不要使用它 - 如果它不是其他的。無論這是Google應該實施的是什麼! – Chameleon

+0

即使可能使用這些方法,因爲所有單獨的下劃線(即'light'私有)都是如此。 如果有疑問,您甚至可以將appengine.ext.db模塊複製到您的應用程序中以確保它不會更改 (以爲我建議不要這樣做),因爲它只是appengine.api.datastore的一個包裝,它本身只包裝appengine.datastore,最後引用的是「 」,被設計爲所有Python數據存儲客戶端庫用於執行查詢的最低級別的API,它提供了一層保護,因此實際的RPC語法可以更改而不會影響客戶端庫「。 –

+0

您的代碼非常好,但是Google沒有授予使用__x的權限,並且大多數_x提示非常好,我認爲沒有人會給出更好的結果!我在代碼中找到了引號,但仍然認爲這樣做風險很小,因爲它可以減少向後兼容性,但是你做了很好的研究。 – Chameleon

1

使用ndb和memcache查詢結果(keys_only)。

def myquery_cached(flush_cache=False): 
    key = 'My Query Key' # make this unique to this query 
    ctx = ndb.get_context() 
    # if flush_cache is True, skip the cache and run the query 
    myclass_keys = None if flush_cache else ctx.memcache_get(key).get_result() 
    if not myclass_keys: 
     myclass_keys = MyClass.query(...).fetch(keys_only=true) # the actual query 
     ctx.memcache_set(key, myclass_keys) # store the keys 
    return ndb.get_multi(myclass_keys)   # this uses ndb's caching 

此代碼被調用一次以填充緩存後,隨後的每個時間都會使用兩個memcache查詢來檢索所有結果。

當你想刷新緩存,通話myquery_cached(真)

相關問題