Go to file
Bertrand Bordage 991bdc7ea0 Adds the coveralls token. 2014-09-29 22:05:45 +02:00
cachalot Clears the cache on test DB creation and destruction. 2014-09-29 22:03:05 +02:00
.coveralls.yml Adds the coveralls token. 2014-09-29 22:05:45 +02:00
.gitignore Version 0.1.0. 2014-09-26 16:53:44 +02:00
AUTHORS.rst Version 0.1.0. 2014-09-26 16:53:44 +02:00
CHANGELOG.rst Version 0.3.0. 2014-09-29 20:05:50 +02:00
LICENSE Version 0.1.0. 2014-09-26 16:53:44 +02:00
README.rst Updates test runner for Django 1.7, PostgreSQL & Redis. 2014-09-29 20:41:34 +02:00
django-cachalot.jpg Version 0.1.0. 2014-09-26 16:53:44 +02:00
requirements.txt Removes django-redis from requirements. 2014-09-29 21:20:30 +02:00
runtests.py Moves an import for Django1.6 compatibility. 2014-09-29 20:43:35 +02:00
setup.py chmod +x setup.py. 2014-09-26 20:27:25 +02:00

README.rst

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

Django-cachalot
===============

Caches your Django ORM queries and automatically invalidates them.

**In alpha, do not use in production**

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


Quick start
-----------

Requirements
............

Django-cachalot currently requires Django 1.6 or 1.7
and `locmem <https://docs.djangoproject.com/en/1.7/topics/cache/#local-memory-caching>`_
or `django-redis <https://github.com/niwibe/django-redis>`_ as your default
cache backend.  It should work with both Python 2 & 3.

Usage
.....

#. `pip install -e git+https://github.com/BertrandBordage/django-cachalot#egg=django-cachalot`
#. Add ``'cachalot',`` to your ``INSTALLED_APPS``
#. Enjoy!


Limits
------

Django-cachalot doesnt cache queries it cant reliably invalidate.
If a SQL query or a part of it is written in pure SQL, it wont be cached.

Thats why ``QuerySet.extra`` with ``select`` or ``where`` arguments,
``Model.objects.raw(…)``, & ``cursor.execute(…)`` queries are not cached.


How django-cachalot works
-------------------------

**(If you dont care/understand, just pretend its magic)**

Reverse engineering
...................

Its 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
...............

- Find out if its thread-safe and test it
- Write tests for `multi-table inheritance <https://docs.djangoproject.com/en/1.7/topics/db/models/#multi-table-inheritance>`_
- Add support for other caches like memcached
- Handle multiple databases
- Add invalidation on migrations in Django 1.7 (& South?)
- Add a ``CACHALOT_ENABLED`` setting
- Add a setting to choose a cache other than ``'default'``
- Use a continuous integration service to test against:

  - Python 2.7, 3.3, & 3.4
  - Django 1.6 & 1.7
  - PostgreSQL, SQLite, & MySQL
  - Redis, Memcached, LocMem

In a more distant future
........................

- Add a setting to choose if we cache ``QuerySet.order_by('?')``
- Cache ``QuerySet.extra`` if none of
  ``set(connection.introspection.table_names())
  - set(connection.introspection.django_table_name())``
  is found in the extra ``select`` and ``where`` queries
- Add a setting to disable caching on ``QuerySet.extra`` when it has ``select``
  or ``where`` rules because we cant reliably detect other databases (and
  meta databases like ``information_schema``) on every database backend
- Maybe parse ``QuerySet.extra`` with ``select`` or ``where`` arguments
  in order to find which tables are implied, and therefore be able
  to cache them


Legacy
------

This work is highly inspired of
`johnny-cache <https://github.com/jmoiron/johnny-cache>`_, another easy-to-use
ORM caching tool!  Its working with Django <= 1.5.
I used it in production during 3 years, its 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``.