Add CACHALOT_ADDITIONAL_TABLES for unmanaged models (#183)

* Add CACHALOT_ADDITIONAL_TABLES for unmanaged models
- Fixes #182
- For doc purposes, we do not want to use table_names and want to continue using django_table_names from connection.introspection to avoid a query to the db every request.
This commit is contained in:
Andrew Chen Wang 2021-05-13 00:44:41 -04:00 committed by GitHub
parent 165cdb6a00
commit 5eaffb4958
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 45 additions and 2 deletions

View file

@ -9,6 +9,7 @@ Whats new in django-cachalot?
- Drop support for Django 2.0-2.1 and Python 3.5 (#181)
- Add support for Pymemcache for Django 3.2+ (#181)
- Reverts #157 with proper fix. (#181)
- Add ``CACHALOT_ADDITIONAL_TABLES`` setting for unmanaged models (#183)
2.3.5
-----

View file

@ -53,6 +53,7 @@ class Settings(object):
CACHALOT_INVALIDATE_RAW = True
CACHALOT_ONLY_CACHABLE_TABLES = ()
CACHALOT_UNCACHABLE_TABLES = ('django_migrations',)
CACHALOT_ADDITIONAL_TABLES = ()
CACHALOT_QUERY_KEYGEN = 'cachalot.utils.get_query_cache_key'
CACHALOT_TABLE_KEYGEN = 'cachalot.utils.get_table_cache_key'
@ -112,6 +113,11 @@ def convert(value):
return frozenset(value)
@Settings.add_converter('CACHALOT_ADDITIONAL_TABLES')
def convert(value):
return list(value)
@Settings.add_converter('CACHALOT_QUERY_KEYGEN')
def convert(value):
return import_string(value)

View file

@ -11,7 +11,7 @@ from django.test.utils import override_settings
from ..api import invalidate
from ..settings import SUPPORTED_ONLY, SUPPORTED_DATABASE_ENGINES
from .models import Test, TestParent, TestChild
from .models import Test, TestParent, TestChild, UnmanagedModel
from .test_utils import TestUtilsMixin
@ -172,6 +172,14 @@ class SettingsTestCase(TestUtilsMixin, TransactionTestCase):
self.assert_query_cached(TestParent.objects.all())
self.assert_query_cached(User.objects.all(), after=1)
def test_uncachable_unmanaged_table(self):
qs = UnmanagedModel.objects.all()
with self.settings(
CACHALOT_UNCACHABLE_TABLES=("cachalot_unmanagedmodel",),
CACHALOT_ADDITIONAL_TABLES=("cachalot_unmanagedmodel",)
):
self.assert_query_cached(qs, after=1)
def test_cache_compatibility(self):
compatible_cache = {
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',

View file

@ -97,7 +97,25 @@ def get_table_cache_key(db_alias, table):
def _get_tables_from_sql(connection, lowercased_sql):
return {t for t in connection.introspection.django_table_names()
if t in lowercased_sql}
+ cachalot_settings.CACHALOT_ADDITIONAL_TABLES if t in lowercased_sql}
def _find_rhs_lhs_subquery(side):
h_class = side.__class__
if h_class is Query:
return side
elif h_class is QuerySet:
return side.query
elif h_class in (Subquery, Exists): # Subquery allows QuerySet & Query
try:
return side.query.query if side.query.__class__ is QuerySet else side.query
except AttributeError: # TODO Remove try/except closure after drop Django 2.2
try:
return side.queryset.query
except AttributeError:
return None
elif h_class in UNCACHABLE_FUNCS:
raise UncachableQuery
def _find_rhs_lhs_subquery(side):

View file

@ -144,6 +144,16 @@ Settings
some issues, especially during tests.
Run ``./manage.py invalidate_cachalot`` after changing this setting.
``CACHALOT_ADDITIONAL_TABLES``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
:Default: ``list()``
:Description:
Sequence of SQL table names that are not included in your Django
apps such as unmanaged models. Cachalot caches models that Django
does not manage, so if you want to ignore/not-cache those models,
then add them here.
``CACHALOT_QUERY_KEYGEN``
~~~~~~~~~~~~~~~~~~~~~~~~~