Fixed #15255 -- Ensured createcachetable honors database routers.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@17114 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Aymeric Augustin 2011-11-19 19:56:31 +00:00
parent c8c71057aa
commit d0eb4693ab
4 changed files with 49 additions and 10 deletions

View File

@ -61,9 +61,7 @@ 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 call_command('createcachetable', cache._table, database=self.connection.alias)
if router.allow_syncdb(self.connection.alias, cache.cache_model_class):
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.cache.backends.db import BaseDatabaseCache
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.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') 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

@ -255,9 +255,7 @@ 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 call_command('createcachetable', cache._table, database=self.connection.alias)
if router.allow_syncdb(self.connection.alias, cache.cache_model_class):
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

@ -16,6 +16,7 @@ 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,
InvalidCacheBackendError) InvalidCacheBackendError)
from django.db import router
from django.http import HttpResponse, HttpRequest, QueryDict from django.http import HttpResponse, HttpRequest, QueryDict
from django.middleware.cache import (FetchFromCacheMiddleware, from django.middleware.cache import (FetchFromCacheMiddleware,
UpdateCacheMiddleware, CacheMiddleware) UpdateCacheMiddleware, CacheMiddleware)
@ -775,6 +776,44 @@ class DBCacheTests(unittest.TestCase, BaseCacheTests):
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(TestCase):
multi_db = True
def test_createcachetable_observes_database_router(self):
old_routers = router.routers
try:
router.routers = [DBCacheRouter()]
# cache table should not be created on 'default'
with self.assertNumQueries(0, using='default'):
management.call_command('createcachetable', 'cache_table',
database='default',
verbosity=0, interactive=False)
# cache table should be created on 'other'
# one query is used to create the table and another one the index
with self.assertNumQueries(2, using='other'):
management.call_command('createcachetable', 'cache_table',
database='other',
verbosity=0, interactive=False)
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'