A
A
axel2018-02-06 21:32:54
Django
axel, 2018-02-06 21:32:54

How to optimize this script?

There is the following script, it is simply readable, so it is clear without explanation what is happening:

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')

How can the code be optimized? There are several tens of thousands of records in the database, it takes about 5 minutes (
What can be done better?

Answer the question

In order to leave comments, you need to log in

2 answer(s)
T
tema_sun, 2018-02-06
@tema_sun

Don't do len(ProblemRating.objects.filter(problem_id__in=item_roads)), do count:
https://docs.djangoproject.com/en/2.0/ref/models/q...

A
Astrohas, 2018-02-06
@Astrohas

first, replace len with .count.
when len is called, jenga gets all the data from the database, generates objects from them, and then displays the number of these objects.
and why are you deleting profiles? Just update and that's it. Well, if you delete it, then instead of update_or_create you create an object manually, and without saving, add it to some list. then use .objects.bulk_create for a quick save.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question