3

I have a postgresql database connected to with django. In database there is lots of big tables which I want their row count. Because of large size of tables this takes a lot of time to execute.

I founded that the approximate count could be retrieved from pg_class. Is there any way to this in Django and not executing raw query?

1

1 Answer 1

3

I propose to use a dedicated package for this named django-postgres-fuzzycount [GitHub]. This package provides a manager that will do the fast counting.

You can install the package with pip (for example in your local environment):

$ pip install django-postgres-fuzzycount

Then you can add the FuzzyCountManager to the models where you want to obtain an approximative count:

from django.db import models
from fuzzycount import FuzzyCountManager

class SomeModel(models.Model):

    #  ... (some fields) ...

    objects = models.Manager()
    approx = FuzzyCountManager()

and then you can count approximatively with:

SomeModel.approx.count()

In case you .filter(..), Django will calculate the real number, since the pg_class table only stores an apprixmative number of rows for the entire table, so:

SomeModel.approx.filter(foo=bar).count()

will take more time (depending on indexes, etc.).

You can also "patch" the objects manager directly, but then obtaining the real number of records might be harder:

from django.db import models
from fuzzycount import FuzzyCountManager

class SomeModel(models.Model):

    #  ... (some fields) ...

    objects = FuzzyCountManager()

It is also nice that if you change the backend database to another database, the FuzzyCountManager(..) will act as a normal Manager, so in case you later change the database system, you do not have to rewrite the managers.

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

10 Comments

I don't want to "patch" the objects directly, because already have a custom manager, Added approx = FuzzyCountManager() but got the error: AttributeError: 'QuerySet' object has no attribute 'approx'
@Miguel: you are likely working with SomeModel.objects.approx, but then it is a QuerySet, so that will not work. Note that .objects is only defined on the model, not on a manager or QuerySet that arises from that model.
@Miguel: you can however simply make a manager in the model approx = FuzzyCountManager(), and another ojbects = models.Manager(), then you thus can work with SomeModel.approx to count the number of elements approximately.
Ok, thanks. But what about count the queryset? That is what I need.
@Miguel: you can count exactly with SomeModel.objects.count() or approximately with SomeModel.approx.count() if you implement it as in the first way (second code fragment).
|

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.