Сортировка Django / Python после получения кэшированных результатов - PullRequest
1 голос
/ 23 мая 2011

Привет,

Несколько быстрых вещей (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 является неподписанным.

У кого-нибудь есть идеи? Я, вероятно, делаю что-то глупое ....

спасибо.

ПРИМЕЧАНИЕ. Обновление внесено изменение operator.attrgetter для operator.itemgetter: удалена ошибка! Этот код выше работает. Проблема была в использовании operator.itemgetter.

Ответы [ 3 ]

4 голосов
/ 23 мая 2011

Функция Python sorted() работает с типами изменяемых списков, которых нет в наборе запросов Django: именно об этом и говорит ваша ошибка. Технически, подписка является актом доступа к элементу списка по его индексу, например:

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

Если вы попробуете это на наборе запросов, он потерпит неудачу с тем же исключением, которое вы получили:

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 голос
/ 23 мая 2011

Есть одна вещь, которая выпадает из вашего примера кода.Похоже, вы рассматриваете свой кеш как надежное хранилище данных.Вы никогда не должны предполагать, что кеш вернет значение.

my_cache_list вероятно None, когда вы получаете TypeError, что означает, что ключ кеша не был найден.Вы всегда должны проверять значение None и восстанавливать значение.

При использовании резервной копии memcache необходимо помнить, что вы можете хранить значения размером до 1 МБ.Значения, превышающие это значение, игнорируются.

0 голосов
/ 23 мая 2011

попробуйте выбрать ваш список перед тем, как поместить его в кеш:

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 )
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...