как не тратить много памяти на манипуляции с моделями Django - PullRequest
1 голос
/ 30 августа 2010

У меня есть следующая модель:

model rank(Models.model):
    username = models.CharField(max_length=200, default=0)
    points = models.IntegerField(default=0)
    rank = models.IntegerFiel(default=0)

То, что я хочу, на основе «точек» пересчитать эту модель, установив результат в поле «ранг».


i=0
user_list = db.Rank.objects.get.all().order_by('-points')

for user in user_list:
   user.rank = i
   user.save()
   i += 1

это работает нормально, но с 1800 пользователями я трачу 130 МБ ПАМЯТИ !!!! Вебфракция хочет меня убить :) 1007 *

как я могу это сделать, не потратив много памяти?

Ответы [ 2 ]

4 голосов
/ 30 августа 2010

Непосредственная причина утечки памяти, вероятно, в том, что для DEBUG установлено значение True.При включенной отладке Django сохраняет все запросы, которые он выполняет, в памяти.Попробуйте отключить DEBUG, и вы увидите, что использование значительно снизится.

1 голос
/ 30 августа 2010

Один из способов сделать это - использовать пользовательский запрос для вычисления ранга на лету. Таким образом, вы оставляете расчет ранга в базе данных. Этот урок содержит хорошее объяснение того, как это сделать.

Вот запрос со связанного веб-сайта, модифицированный в соответствии с вашей моделью:

SELECT r1.username, r1.points, COUNT(r2.points) rank
FROM app_rank r1, app_rank r2 
WHERE r1.points <= r2.points or (r1.points = r2.points and r1.username = r2.username) 
GROUP BY r1.username, r1.points
ORDER BY r1.points DESC, r1.username DESC;

Что касается примечания, вы можете переписать цикл без использования переменной счетчика i.

for index, user in enumerate(user_list):
   user.rank = index + 1
   user.save()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...