mirror of
https://github.com/django/django.git
synced 2024-12-22 17:16:24 +00:00
Fixed #32772 -- Made database cache count size once per set.
This commit is contained in:
parent
12b19a1d76
commit
5a8e8f80bb
1
AUTHORS
1
AUTHORS
@ -641,6 +641,7 @@ answer newbie questions, and generally made Django that much better:
|
|||||||
Michael S. Brown <michael@msbrown.net>
|
Michael S. Brown <michael@msbrown.net>
|
||||||
Michael Hall <mhall1@ualberta.ca>
|
Michael Hall <mhall1@ualberta.ca>
|
||||||
Michael Josephson <http://www.sdjournal.com/>
|
Michael Josephson <http://www.sdjournal.com/>
|
||||||
|
Michael Lissner <mike@free.law>
|
||||||
Michael Manfre <mmanfre@gmail.com>
|
Michael Manfre <mmanfre@gmail.com>
|
||||||
michael.mcewan@gmail.com
|
michael.mcewan@gmail.com
|
||||||
Michael Placentra II <someone@michaelplacentra2.net>
|
Michael Placentra II <someone@michaelplacentra2.net>
|
||||||
|
12
django/core/cache/backends/db.py
vendored
12
django/core/cache/backends/db.py
vendored
@ -128,7 +128,7 @@ class DatabaseCache(BaseDatabaseCache):
|
|||||||
exp = datetime.fromtimestamp(timeout, tz=tz)
|
exp = datetime.fromtimestamp(timeout, tz=tz)
|
||||||
exp = exp.replace(microsecond=0)
|
exp = exp.replace(microsecond=0)
|
||||||
if num > self._max_entries:
|
if num > self._max_entries:
|
||||||
self._cull(db, cursor, now)
|
self._cull(db, cursor, now, num)
|
||||||
pickled = pickle.dumps(value, self.pickle_protocol)
|
pickled = pickle.dumps(value, self.pickle_protocol)
|
||||||
# The DB column is expecting a string, so make sure the value is a
|
# The DB column is expecting a string, so make sure the value is a
|
||||||
# string, not bytes. Refs #19274.
|
# string, not bytes. Refs #19274.
|
||||||
@ -247,7 +247,7 @@ class DatabaseCache(BaseDatabaseCache):
|
|||||||
)
|
)
|
||||||
return cursor.fetchone() is not None
|
return cursor.fetchone() is not None
|
||||||
|
|
||||||
def _cull(self, db, cursor, now):
|
def _cull(self, db, cursor, now, num):
|
||||||
if self._cull_frequency == 0:
|
if self._cull_frequency == 0:
|
||||||
self.clear()
|
self.clear()
|
||||||
else:
|
else:
|
||||||
@ -255,10 +255,10 @@ class DatabaseCache(BaseDatabaseCache):
|
|||||||
table = connection.ops.quote_name(self._table)
|
table = connection.ops.quote_name(self._table)
|
||||||
cursor.execute("DELETE FROM %s WHERE expires < %%s" % table,
|
cursor.execute("DELETE FROM %s WHERE expires < %%s" % table,
|
||||||
[connection.ops.adapt_datetimefield_value(now)])
|
[connection.ops.adapt_datetimefield_value(now)])
|
||||||
cursor.execute("SELECT COUNT(*) FROM %s" % table)
|
deleted_count = cursor.rowcount
|
||||||
num = cursor.fetchone()[0]
|
remaining_num = num - deleted_count
|
||||||
if num > self._max_entries:
|
if remaining_num > self._max_entries:
|
||||||
cull_num = num // self._cull_frequency
|
cull_num = remaining_num // self._cull_frequency
|
||||||
cursor.execute(
|
cursor.execute(
|
||||||
connection.ops.cache_key_culling_sql() % table,
|
connection.ops.cache_key_culling_sql() % table,
|
||||||
[cull_num])
|
[cull_num])
|
||||||
|
13
tests/cache/tests.py
vendored
13
tests/cache/tests.py
vendored
@ -40,6 +40,7 @@ from django.test import (
|
|||||||
ignore_warnings, override_settings,
|
ignore_warnings, override_settings,
|
||||||
)
|
)
|
||||||
from django.test.signals import setting_changed
|
from django.test.signals import setting_changed
|
||||||
|
from django.test.utils import CaptureQueriesContext
|
||||||
from django.utils import timezone, translation
|
from django.utils import timezone, translation
|
||||||
from django.utils.cache import (
|
from django.utils.cache import (
|
||||||
get_cache_key, learn_cache_key, patch_cache_control, patch_vary_headers,
|
get_cache_key, learn_cache_key, patch_cache_control, patch_vary_headers,
|
||||||
@ -1117,6 +1118,18 @@ class DBCacheTests(BaseCacheTests, TransactionTestCase):
|
|||||||
with self.assertNumQueries(1):
|
with self.assertNumQueries(1):
|
||||||
cache.delete_many(['a', 'b', 'c'])
|
cache.delete_many(['a', 'b', 'c'])
|
||||||
|
|
||||||
|
def test_cull_count_queries(self):
|
||||||
|
old_max_entries = cache._max_entries
|
||||||
|
# Force _cull to delete on first cached record.
|
||||||
|
cache._max_entries = -1
|
||||||
|
with CaptureQueriesContext(connection) as captured_queries:
|
||||||
|
try:
|
||||||
|
cache.set('force_cull', 'value', 1000)
|
||||||
|
finally:
|
||||||
|
cache._max_entries = old_max_entries
|
||||||
|
num_count_queries = sum('COUNT' in query['sql'] for query in captured_queries)
|
||||||
|
self.assertEqual(num_count_queries, 1)
|
||||||
|
|
||||||
def test_delete_cursor_rowcount(self):
|
def test_delete_cursor_rowcount(self):
|
||||||
"""
|
"""
|
||||||
The rowcount attribute should not be checked on a closed cursor.
|
The rowcount attribute should not be checked on a closed cursor.
|
||||||
|
Loading…
Reference in New Issue
Block a user