Skip to main content

Caches your Django ORM queries and automatically invalidates them.

Project description

Caches your Django ORM queries and automatically invalidates them.

https://raw.github.com/BertrandBordage/django-cachalot/master/django-cachalot.jpg

Project status:

Currently in beta, do not use in production

http://img.shields.io/pypi/v/django-cachalot.svg?style=flat-square http://img.shields.io/travis/BertrandBordage/django-cachalot/master.svg?style=flat-square http://img.shields.io/coveralls/BertrandBordage/django-cachalot/master.svg?style=flat-square http://img.shields.io/scrutinizer/g/BertrandBordage/django-cachalot/master.svg?style=flat-square http://img.shields.io/gratipay/BertrandBordage.svg?style=flat-square

Quick start

Requirements

  • Django 1.6 or 1.7

  • Python 2.6, 2.7, 3.2, 3.3, or 3.4

  • django-redis, memcached (or locmem, but it’s not shared between processes, so don’t use it with RQ or Celery)

  • PostgreSQL, MySQL or SQLite

Usage

  1. pip install django-cachalot

  2. Add 'cachalot', to your INSTALLED_APPS

  3. Enjoy!

Settings

Setting

Default value

Description

CACHALOT_ENABLED

True

If set to False, disables SQL caching but keeps invalidating to avoid stale cache

CACHALOT_CACHE

'default'

Alias of the cache from CACHES used by django-cachalot

These settings can be changed whenever you want. You have to use cachalot_settings as a context manager, a decorator, or simply by changing its attributes:

from cachalot.settings import cachalot_settings

with cachalot_settings(CACHALOT_ENABLED=False):
    # SQL queries are not cached in this block

@cachalot_settings(CACHALOT_CACHE='another_alias')
def your_function():
    # What’s in this function uses another cache

# Globally disables SQL caching until you set it back to True
cachalot_settings.CACHALOT_ENABLED = False

In tests, you can use Django’s testing tools as well as cachalot_settings. The only difference is that you can’t use cachalot_settings to decorate a class.

Limits

Locmem

Locmem is a just a dict stored in a single Python process. It’s not shared between processes, so don’t use locmem with django-cachalot in a multi-processes project, if you use RQ or Celery for instance.

Raw queries

Django-cachalot doesn’t cache queries it can’t reliably invalidate. If a SQL query or a part of it is written in pure SQL, it won’t be cached. That’s why QuerySet.extra with select or where arguments, Model.objects.raw(…), & cursor.execute(…) queries are not cached.

Bug reports, questions, discussion, new features

  • If you spotted a bug, please file a precise bug report on GitHub

  • If you have a question on how django-cachalot works or to simply discuss, go to our Google group.

  • If you want to add a feature:

    • if you have an idea on how to implement it, you can fork the project and send a pull request, but please open an issue first, because someone else could already be working on it

    • if you’re sure that it’s a must-have feature, open an issue

    • if it’s just a vague idea, please ask on google groups before

How django-cachalot works

(If you don’t care/understand, just pretend it’s magic)

Reverse engineering

It’s a lot of Django reverse engineering combined with a strong test suite. Such a test suite is crucial for a reverse engineering project. If some important part of Django changes and breaks the expected behaviour, you can be sure that the test suite will fail.

Monkey patching

django-cachalot modifies Django in place during execution to add a caching tool just before SQL queries are executed. We detect which cache keys must be removed when some data is created/changed/deleted on the database.

What still needs to be done

For version 1.0

  • Add a lock around SQL query executions to avoid a stale cache issue if an invalidation of the same table(s) occurs concurrently

  • Write tests for multi-table inheritance

In a more distant future

  • Add a setting to choose if we cache QuerySet.order_by('?')

  • Use connection.introspection.table_names() to detect which tables are implied in a QuerySet.extra

Legacy

This work is highly inspired of johnny-cache, another easy-to-use ORM caching tool! It’s working with Django <= 1.5. I used it in production during 3 years, it’s an excellent module!

Unfortunately, we failed to make it migrate to Django 1.6 (I was involved). It was mostly because of the transaction system that was entirely refactored.

I also noticed a few advanced invalidation issues when using QuerySet.extra and some complex cases implying multi-table inheritance and related ManyToManyField.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

django-cachalot-0.8.1.tar.gz (19.5 kB view hashes)

Uploaded Source

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page