2

I'm trying to figure out a good way to get a few analytics counts from my DB without doing a bunch of queries and somehow doing one

What I have right now is a function that returns counts

def get_counts(self):
    return {
        'item_one_counts'  : self.items_one.count(),
        'item_two_counts'  : self.items_two.count(),
        'item_three_count' : self.items_three.count(),
    }

etc.

I know I can do this with a raw query that does a SELECT as count1,2,3 FROM table X

Is there a more django-y way to do this?

1
  • Did you check my solution? Commented Dec 18, 2014 at 11:06

1 Answer 1

1

You're a tad late if you want to get the counts in an instance method. The easiest way to optimize this is by using annotations in the initial query:

obj = MyModel.objects.annotate(item_one_count=Count('items_one')) \
             .annotate(item_two_count=Count('items_two')) \
             .annotate(item_three_count=Count('items_three')) \
             .get(...)

Another good optimization is to cache the results, e.g.:

MyModel(models.Model):
    def get_item_one_count(self):
        if not hasattr(self, '_item_one_count'):
            self._item_one_count = self.items_one.count()
        return self._item_one_count

    ...

    def get_counts(self):
        return {
                'item_one_counts'  : self.get_item_one_count(),
                'item_two_counts'  : self.get_item_two_count(),
                'item_three_count' : self.get_item_three_count(),
        }

Combine these methods (i.e. .annotate(_item_one_count=Count('items_one'))), and you can optimize the counts into a single query when you have control over the query, while having fallback method in case you can't annotate the results.

Another option is to perform the annotation in your model manager, but you will no longer have fine-grained control over the queries.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.