Fixed #15255 -- Stopped database cache from ignoring database routers when creating the cache table. Thanks, aaugustin.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@16510 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Jannis Leidel 2011-07-04 21:53:17 +00:00
parent 94a38dfd0e
commit 6de65ab76f
4 changed files with 47 additions and 11 deletions

View File

@ -33,8 +33,6 @@ class SpatiaLiteCreation(DatabaseCreation):
for cache_alias in settings.CACHES: for cache_alias in settings.CACHES:
cache = get_cache(cache_alias) cache = get_cache(cache_alias)
if isinstance(cache, BaseDatabaseCache): if isinstance(cache, BaseDatabaseCache):
from django.db import router
if router.allow_syncdb(self.connection.alias, cache.cache_model_class):
call_command('createcachetable', cache._table, database=self.connection.alias) call_command('createcachetable', cache._table, database=self.connection.alias)
# Get a cursor (even though we don't need one yet). This has # Get a cursor (even though we don't need one yet). This has
# the side effect of initializing the test database. # the side effect of initializing the test database.

View File

@ -1,7 +1,8 @@
from optparse import make_option from optparse import make_option
from django.core.management.base import LabelCommand from django.core.management.base import LabelCommand
from django.db import connections, transaction, models, DEFAULT_DB_ALIAS from django.core.cache.backends.db import BaseDatabaseCache
from django.db import connections, router, transaction, models, DEFAULT_DB_ALIAS
class Command(LabelCommand): class Command(LabelCommand):
help = "Creates the table needed to use the SQL cache backend." help = "Creates the table needed to use the SQL cache backend."
@ -18,8 +19,11 @@ class Command(LabelCommand):
requires_model_validation = False requires_model_validation = False
def handle_label(self, tablename, **options): def handle_label(self, tablename, **options):
alias = options.get('database', DEFAULT_DB_ALIAS) db = options.get('database', DEFAULT_DB_ALIAS)
connection = connections[alias] cache = BaseDatabaseCache(tablename, {})
if not router.allow_syncdb(db, cache.cache_model_class):
return
connection = connections[db]
fields = ( fields = (
# "key" is a reserved word in MySQL, so use "cache_key" instead. # "key" is a reserved word in MySQL, so use "cache_key" instead.
models.CharField(name='cache_key', max_length=255, unique=True, primary_key=True), models.CharField(name='cache_key', max_length=255, unique=True, primary_key=True),
@ -50,4 +54,4 @@ class Command(LabelCommand):
curs.execute("\n".join(full_statement)) curs.execute("\n".join(full_statement))
for statement in index_output: for statement in index_output:
curs.execute(statement) curs.execute(statement)
transaction.commit_unless_managed(using=alias) transaction.commit_unless_managed(using=db)

View File

@ -261,8 +261,6 @@ class BaseDatabaseCreation(object):
for cache_alias in settings.CACHES: for cache_alias in settings.CACHES:
cache = get_cache(cache_alias) cache = get_cache(cache_alias)
if isinstance(cache, BaseDatabaseCache): if isinstance(cache, BaseDatabaseCache):
from django.db import router
if router.allow_syncdb(self.connection.alias, cache.cache_model_class):
call_command('createcachetable', cache._table, database=self.connection.alias) call_command('createcachetable', cache._table, database=self.connection.alias)
# Get a cursor (even though we don't need one yet). This has # Get a cursor (even though we don't need one yet). This has

View File

@ -13,10 +13,11 @@ from django.conf import settings
from django.core import management from django.core import management
from django.core.cache import get_cache, DEFAULT_CACHE_ALIAS from django.core.cache import get_cache, DEFAULT_CACHE_ALIAS
from django.core.cache.backends.base import CacheKeyWarning from django.core.cache.backends.base import CacheKeyWarning
from django.db import connections, router
from django.http import HttpResponse, HttpRequest, QueryDict from django.http import HttpResponse, HttpRequest, QueryDict
from django.middleware.cache import FetchFromCacheMiddleware, UpdateCacheMiddleware, CacheMiddleware from django.middleware.cache import FetchFromCacheMiddleware, UpdateCacheMiddleware, CacheMiddleware
from django.test import RequestFactory from django.test import RequestFactory
from django.test.utils import get_warnings_state, restore_warnings_state from django.test.utils import get_warnings_state, restore_warnings_state, override_settings
from django.utils import translation from django.utils import translation
from django.utils import unittest from django.utils import unittest
from django.utils.cache import patch_vary_headers, get_cache_key, learn_cache_key from django.utils.cache import patch_vary_headers, get_cache_key, learn_cache_key
@ -757,6 +758,41 @@ class DBCacheTests(unittest.TestCase, BaseCacheTests):
self.cache = get_cache('db://%s?max_entries=30&cull_frequency=0' % self._table_name) self.cache = get_cache('db://%s?max_entries=30&cull_frequency=0' % self._table_name)
self.perform_cull_test(50, 18) self.perform_cull_test(50, 18)
class DBCacheRouter(object):
"""A router that puts the cache table on the 'other' database."""
def db_for_read(self, model, **hints):
if model._meta.app_label == 'django_cache':
return 'other'
def db_for_write(self, model, **hints):
if model._meta.app_label == 'django_cache':
return 'other'
def allow_syncdb(self, db, model):
if model._meta.app_label == 'django_cache':
return db == 'other'
class CreateCacheTableForDBCacheTests(unittest.TestCase):
@override_settings(DEBUG=True)
def test_createcachetable_observes_database_router(self):
old_routers = router.routers
try:
router.routers = [DBCacheRouter()]
# cache table should not be created on 'default'
management.call_command('createcachetable', 'cache_table',
database='default',
verbosity=0, interactive=False)
self.assertEqual(len(connections['default'].queries), 0)
# cache table should be created on 'other'
management.call_command('createcachetable', 'cache_table',
database='other',
verbosity=0, interactive=False)
self.assertNotEqual(len(connections['other'].queries), 0)
finally:
router.routers = old_routers
class LocMemCacheTests(unittest.TestCase, BaseCacheTests): class LocMemCacheTests(unittest.TestCase, BaseCacheTests):
backend_name = 'django.core.cache.backends.locmem.LocMemCache' backend_name = 'django.core.cache.backends.locmem.LocMemCache'