2010-07-03 88 views
1

我正在嘗試使用燒杯的緩存庫,但無法使其工作。無法獲取燒杯緩存工作

這是我的測試代碼。

class IndexHandler(): 
    @cache.cache('search_func', expire=300) 
    def get_results(self, query): 
     results = get_results(query) 
     return results 

    def get(self, query): 
     results = self.get_results(query) 
     return render_index(results=results) 

我已經試過例子燒杯的文檔中,但我看到的是

<type 'exceptions.TypeError'> at/
can't pickle generator objects 

顯然我失去了一些東西,但我無法找到一個解決方案。

順便說一句,如果緩存類型設置爲「文件」,則會出現此問題。

回答

1

我看到beaker文檔沒有明確提到這一點,但顯然,裝飾函數必須醃製它所調用的參數(用作緩存中的鍵的一部分,以檢查條目是否存在以及否則稍後添加它) - 並且,生成器對象不可pickleable,因爲錯誤消息告訴你。這意味着query是一個生成器對象,當然。

你應該爲了使用燒杯或做什麼任何其他類型的緩存是通過代替query發電機對象時,(與pickle)parameters從該查詢可內置周圍, - 字符串,數字,字典,列表,元組等等,它們以任何方式組成,只要在get_results的函數體內就可以輕鬆地進行排列,並且易於從「及時」構建查詢。這樣,參數將被pickleable和緩存將工作。

如果方便的話,你可以構建一個簡單的pickleable類,它的實例「代表」查詢,模擬你需要的任何初始化和參數設置,並且只在某些需要實際查詢對象的方法時才執行實時實例化叫做。但這只是一個「便利」的想法,並沒有改變前面段落中解釋的基本概念。

+1

我懷疑這是不可查看的結果,而不是查詢。 – 2010-07-10 16:45:14

+0

@Marius,我相信'query'是一個生成器,因此不可pickleable(結果本身是否也是一個單獨的問題)。 – 2010-07-10 17:02:45

+0

我懷疑結果是不可取的,我認爲它將緩存存儲在數據庫或文件中,因此它必須序列化鍵和值。從上下文(緩存命名空間被稱爲'search_func'),我會說'query'只是一個字符串 – 2011-01-02 17:15:16

1

嘗試return list(results)而不是return results,看看是否有幫助。

燒杯文件緩存需要能夠緩存緩存鍵和值;大多數迭代器和生成器都是不可打開的。

3

如果您將燒杯配置爲保存到文件系統,您可以很容易地看到每個參數也被醃製。例如:

tp3 
sS'tags <myapp.controllers.tags.TagsController object at 0x103363c10> <MySQLdb.cursors.Cursor object at 0x103363dd0> apple' 
p4 

請注意,緩存「密鑰」不僅包含我的關鍵字「apple」,還包含特定於實例的信息。這很糟糕,因爲特別是'自我'在調用中不會相同。緩存將導致每一次錯過(並且將被無用的密鑰填滿)。

帶有緩存註釋的方法應該只有有參數對應於你想要的任何「密鑰」。爲了解釋這一點,我們假設你想要存儲「約翰」對應值555-1212並且你想緩存這個事實。你的函數不應該接受任何東西,除了一個字符串作爲參數。你傳入的任何參數都應該從調用到調用保持不變,所以像「self」這樣的東西會很糟糕。

使這項工作的一個簡單的方法是內聯函數,以便您不需要傳遞任何超出密鑰。例如:

def index(self): 

    # some code here 

    # suppose 'place' is a string that you're using as a key. maybe 
    # you're caching a description for cities and 'place' would be "New York" 
    # in one instance 

    @cache_region('long_term', 'place_desc') 
    def getDescriptionForPlace(place): 
     # perform expensive operation here 
     description = ... 
     return description 

    # this will either fetch the data or just load it from the cache 
    description = getDescriptionForPlace(place) 

您的緩存文件應該類似於以下內容。注意只有'place_desc'和'John'被保存爲一個關鍵字。

tp3 
sS'place_desc John' 
p4