获取缓存结果后的Django/Python排序

获取缓存结果后的Django/Python排序,python,django,sorting,memcached,Python,Django,Sorting,Memcached,您好 一些简单的东西(django 1.2.3、Python2.6、memcached) 我有一个函数,我首先执行一个有点昂贵的查询,当我执行这个查询时,我执行一个order\u by。然后我更新了一些可能改变结果顺序的值。然后我将所有的值都放在缓存中 然后在另一个函数中,我得到缓存,我想利用结果,使它们再次有序 这大概是这样的 function 1(): mylist = myevent.people.order_by('-score') ....do up date....

您好

一些简单的东西(django 1.2.3、Python2.6、memcached)

我有一个函数,我首先执行一个有点昂贵的查询,当我执行这个查询时,我执行一个order\u 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 )

根据其他帖子,我认为这应该行得通,但我得到一个类型错误,说我的缓存列表不可复制

有人有什么想法吗?我可能在做傻事

谢谢


注意:更新使operator.itemgetter的change operator.attrgetter删除错误!上面的代码确实有效。问题在于使用运算符.itemgetter。

在缓存中设置列表之前,请尝试对其进行pickle处理:

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 )

在缓存中设置列表之前,请尝试对其进行pickle:

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 )

有一件事从您的示例代码中跳出来。您似乎将缓存视为可靠的数据存储。永远不要假设缓存将返回一个值

当您获得
类型错误时,
我的缓存列表
可能是
,这意味着找不到缓存键。您应该始终测试
None
值并重新生成该值


在使用memcache备份时,您需要记住,您只能存储最大为1MB的值。大于此值的值将被自动丢弃。

示例代码中有一个跳出。您似乎将缓存视为可靠的数据存储。永远不要假设缓存将返回一个值

当您获得
类型错误时,
我的缓存列表
可能是
,这意味着找不到缓存键。您应该始终测试
None
值并重新生成该值


在使用memcache备份时,您需要记住,您只能存储最大为1MB的值。大于此值的值将被静默丢弃。

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)

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)


出现错误时,
my\u cache\u list
等于什么?它可能是
,因为没有缓存值?最好将
list
存储在缓存中,而不是queryset。确实要这样做吗?当您将新条件应用于已缓存的查询集时,它将执行新的数据库查询,因为它需要重新计算查询集。最好将查询集的结果保存为列表,然后通过Python而不是Django的查询api对其进行排序。@DrTyrsa为什么缓存列表比缓存查询集更好?出现错误时,
my_cache_list
等于什么?它可能是
,因为没有缓存值?最好将
list
存储在缓存中,而不是queryset。确实要这样做吗?当您将新条件应用于已缓存的查询集时,它将执行新的数据库查询,因为它需要重新计算查询集。最好将查询集的结果保存为列表,然后通过Python而不是Django的查询api对其进行排序。@DrTyrsa为什么缓存列表比缓存查询集更好?您不需要在将值放入缓存之前对其进行pickle,这是为您处理的。您不需要在将值放入缓存之前对其进行pickle,你的回答很有道理,我认为你是对的。你对如何实施我正在尝试做的事情有什么建议吗?你真的认为把它变成一个真实的列表是一个好主意吗?如果没有更多的信息和一些(或者可能很多)基准测试,我真的不认为我能回答这个问题。但是如果需要在每次缓存访问时计算排序器,则索引字段上的数据库排序可能比Python排序快。如果排序顺序在缓存访问中保持稳定,最好在缓存列表之前对列表进行排序。@tawmas-我有一个高负载的应用程序,所以我试图最小化与数据库的连接并最大限度地提高memcached的使用率。问题是代码中有两个地方需要缓存。1) 其中我更新了分数,2)我想为模板设置视图以显示分数。我试图对这两个操作使用相同的缓存,但可能值得在更新后创建一个排序列表,并按照一些人的建议进行缓存。是什么让您觉得queryset不支持此操作?而且自己检查也不是很困难。@Tawmas我尝试了
lst[0]
,它返回了queryset中的第一项。事实上,这是获得第一项最明显的方式。这是有记录的。我宁愿引用它:“去