2011-05-23 33 views
1

Greetings,獲取緩存結果後的Django/Python排序

一些快速的東西(django 1.2.3,python 2.6,memcached)。

我有一個功能,我首先做一個有點貴的查詢,當我做這個查詢時,我做了一個oder_by。然後我更新一些可能會改變結果順序的值。然後我把所有的值放在緩存中。

然後在另一個函數中,我得到了緩存,我想對結果進行求值,以便它們再次按順序排列。

所以這將是類似的東西。

function 1(): 
    mylist = myevent.people.order_by('-score') 
    ....do up date.... 
    cache.set(cache_key,mylist) 

function(2): 
    my_cache_list = cache.get(cache_key) 
    newlist = sorted(my_cache_list,key=operator.attrgetter('score'), reverse=True) 

基於其他職位我認爲這應該工作,但我得到一個類型錯誤說my_cache_list是unsubsriptable。

任何人有任何想法?我可能做一些愚蠢的事情......

謝謝。

注意:更新使operator.itemgetter更改operator.attrgetter刪除錯誤!上面的代碼確實有效。問題在於使用operator.itemgetter。

+0

當錯誤出現時,my_cache_list等於什麼?可能是'None',因爲沒有緩存的值?最好將'list'存儲在緩存中,而不是queryset。 – DrTyrsa 2011-05-23 07:43:01

+1

您確定要這麼做嗎?當您將新條件應用於已經緩存的查詢集時,它將執行新的數據庫查詢,因爲它需要重新評估查詢集。最好將查詢集的結果保存爲列表,然後通過Python對它們進行排序,而不是使用Django的查詢API。 – 2011-05-23 08:37:05

+0

@DTTyrsa爲什麼緩存列表比queryset更好? – 2011-05-23 16:57:20

回答

4

Python函數sorted()適用於可變列表類型,Django查詢集不是這樣:這就是你所得到的錯誤基本上告訴你。從技術上說,下標是其索引訪問列表元素,像這樣的行爲:

list = ['a', 'b', 'c'] 
list[0] # This is a subscript 

如果你試穿的一個QuerySet,它會失敗,你得到了同樣的異常:

list = MyModel.objects.all() 
list[0] # This subscript will fail: a queryset doesn't support the operation 

如果你想保留加載有序查詢集的方案,緩存結果並重新排序它們的緩存訪問權限,則必須將查詢集變成真正的列表並將其存儲在緩存中(這將佔用更多的緩存空間,儘管)。在你的函數1中:

qs = myevent.people.order_by('-score') 
mylist = list(qs.all()) 
....do up date.... 
cache.set(cache_key, mylist) 
+1

很好的第一個回答tawmas。 – thomasfedb 2011-05-23 13:02:54

+0

你的回答很有道理,我認爲你是對的。你有建議如何實施我想要做的事情嗎?你認爲真的把它變成真正的清單是個好主意嗎? – 2011-05-23 14:04:25

+1

如果沒有更多的信息和一些(或者可能是很多的)基準測試,我並不認爲我可以回答。但是...如果需要在每個緩存訪問時計算sorder,那麼索引字段上的數據庫排序可能會比Python排序更快。如果排序順序在緩存訪問中保持穩定,最好在緩存之前排序列表。 – tawmas 2011-05-23 14:29:53

-1

嘗試你在高速緩存中之前鹹菜列表:

import cPickle as pickle 

cache.set(pickle.dumps(mylist)) 


function(2): 
    my_cache_list = cache.get(cache_key) 
    newlist = sorted(pickle.loads(my_cache_list),key=operator.itemgetter('score'), reverse=True) 
+0

在將其放入緩存之前,您不需要醃製一個值,該值是爲您處理的。 – 2011-05-23 10:04:49

1

有一兩件事,從你的示例代碼跳了出來。您似乎將您的緩存視爲可靠的數據存儲。你不應該假設緩存會返回一個值。

my_cache_list可能是None當您得到TypeError,這意味着緩存鍵未找到。您應該始終測試None值並重新生成該值。

當你使用memcache時,你需要記住你只能存儲大小爲1MB的值。大於此的值將被默默丟棄。

+0

你在幾點上是正確的。但只是跟進一些事情。 1)這只是一個示例代碼集,在真正的代碼中如果沒有緩存,我做一個數據庫查詢然後創建緩存。 2)我知道結果相對較小。但我確實有一個高負載的應用程序,所以我試圖最小化任何數據庫命中,我可以。 3)我確定緩存中有東西,因爲如果我跳過我正在嘗試做的事情,它會顯示一些東西。 – 2011-05-23 14:40:45