@Antoine

Как оптимизировать этот скрипт?

Имеется следующий скрипт, он просто читается, так что, понятно без пояснений, что происходит:

def handle(self, *args, **options):
        start_time = time.clock()
        print('START UPDATING PROFILES')
        users = User.objects.all()
        Profile.objects.all().delete()
        for user_item in users:
            item_roads = Problem.objects.filter(user=user_item.id)
            roads_count = len(item_roads)
            posted_votes_count = len(ProblemRating.objects.filter(user=user_item.id).exclude(problem_id__in=item_roads))
            recd_votes_count = len(ProblemRating.objects.filter(problem_id__in=item_roads))
            posted_comments_count = len(ProblemComment.objects.filter(user=user_item.id).exclude(problem_id__in=item_roads))
            recd_comments_count = len(ProblemComment.objects.filter(problem_id__in=item_roads))
            repaired_roads = len(item_roads.filter(condition_id=config.REPAIRED))
            patched_roads = len(item_roads.filter(condition_id=config.PATCHED))
            planned_roads = len(item_roads.filter(condition_id__in=[x.strip() for x in config.PLANNING.split(',')]))
            obj, created = Profile.objects.update_or_create(
                user_id=user_item.id,
                defaults={
                    'roads_count': roads_count,
                    'posted_votes_count': posted_votes_count,
                    'recd_votes_count': recd_votes_count,
                    'posted_comments_count': posted_comments_count,
                    'recd_comments_count': recd_comments_count,
                    'average_comments_count': int(recd_votes_count / roads_count) if roads_count else 0,
                    'repaired_roads_count': repaired_roads,
                    'patched_roads_count': patched_roads,
                    'planned_roads_count': planned_roads,
                }
            )
        print('UPDATING PROFILES FINISHED OF ' + str(time.clock() - start_time) + ' seconds')


Как можно оптимизировать код? В базе несколько десятков тысяч записей, выполняется порядка 5 минут(
Что можно сделать лучше?
  • Вопрос задан
  • 211 просмотров
Пригласить эксперта
Ответы на вопрос 2
tema_sun
@tema_sun
Не делайте len(ProblemRating.objects.filter(problem_id__in=item_roads)), делайте count:
ProblemRating.objects.filter(problem_id__in=item_roads).count()


https://docs.djangoproject.com/en/2.0/ref/models/q...
Ответ написан
Astrohas
@Astrohas
Python/Django Developer
для начала замените len на .count.
при вызове len дженга получает все данные из базы, генерирует из них объекты, а потом выводит количество этих объектов.
и зачем вы удаляете профили? Просто обновляйте и все. Ну если же и удаляете, то вместо update_or_create создаете объект вручную, и не сохранив добавьте в какойто список. потом используйте .objects.bulk_create для быстрого сохранения.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы