diff --git a/django/contrib/gis/db/backends/spatialite/creation.py b/django/contrib/gis/db/backends/spatialite/creation.py
index 27332b9..b85479e 100644
a
|
b
|
class SpatiaLiteCreation(DatabaseCreation):
|
54 | 54 | interactive=False, |
55 | 55 | database=self.connection.alias) |
56 | 56 | |
57 | | from django.core.cache import get_cache |
58 | | from django.core.cache.backends.db import BaseDatabaseCache |
59 | | for cache_alias in settings.CACHES: |
60 | | cache = get_cache(cache_alias) |
61 | | if isinstance(cache, BaseDatabaseCache): |
62 | | call_command('createcachetable', cache._table, database=self.connection.alias) |
| 57 | call_command('createcachetable', database=self.connection.alias) |
63 | 58 | |
64 | 59 | # Get a cursor (even though we don't need one yet). This has |
65 | 60 | # the side effect of initializing the test database. |
diff --git a/django/core/management/commands/createcachetable.py b/django/core/management/commands/createcachetable.py
index 411042e..d5d8bba 100644
a
|
b
|
|
1 | 1 | from optparse import make_option |
2 | 2 | |
| 3 | from django.conf import settings |
| 4 | from django.core.cache import get_cache |
3 | 5 | from django.core.cache.backends.db import BaseDatabaseCache |
4 | | from django.core.management.base import LabelCommand, CommandError |
| 6 | from django.core.management.base import BaseCommand, CommandError |
5 | 7 | from django.db import connections, router, transaction, models, DEFAULT_DB_ALIAS |
6 | 8 | from django.db.utils import DatabaseError |
7 | 9 | from django.utils.encoding import force_text |
8 | 10 | |
9 | 11 | |
10 | | class Command(LabelCommand): |
11 | | help = "Creates the table needed to use the SQL cache backend." |
12 | | args = "<tablename>" |
13 | | label = 'tablename' |
| 12 | class Command(BaseCommand): |
| 13 | help = "Creates the tables needed to use the SQL cache backend." |
14 | 14 | |
15 | | option_list = LabelCommand.option_list + ( |
| 15 | option_list = BaseCommand.option_list + ( |
16 | 16 | make_option('--database', action='store', dest='database', |
17 | 17 | default=DEFAULT_DB_ALIAS, help='Nominates a database onto ' |
18 | | 'which the cache table will be installed. ' |
| 18 | 'which the cache tables will be installed. ' |
19 | 19 | 'Defaults to the "default" database.'), |
20 | 20 | ) |
21 | 21 | |
22 | 22 | requires_model_validation = False |
23 | 23 | |
24 | | def handle_label(self, tablename, **options): |
| 24 | def handle(self, *tablenames, **options): |
25 | 25 | db = options.get('database') |
| 26 | self.verbosity = int(options.get('verbosity')) |
| 27 | if len(tablenames): |
| 28 | # Legacy behaviour, tablename specified as argument |
| 29 | for tablename in tablenames: |
| 30 | self.create_table(db, tablename) |
| 31 | else: |
| 32 | for cache_alias in settings.CACHES: |
| 33 | cache = get_cache(cache_alias) |
| 34 | if isinstance(cache, BaseDatabaseCache): |
| 35 | self.create_table(db, cache._table) |
| 36 | |
| 37 | def create_table(self, database, tablename): |
26 | 38 | cache = BaseDatabaseCache(tablename, {}) |
27 | | if not router.allow_syncdb(db, cache.cache_model_class): |
| 39 | if not router.allow_syncdb(database, cache.cache_model_class): |
28 | 40 | return |
29 | | connection = connections[db] |
| 41 | connection = connections[database] |
30 | 42 | fields = ( |
31 | 43 | # "key" is a reserved word in MySQL, so use "cache_key" instead. |
32 | 44 | models.CharField(name='cache_key', max_length=255, unique=True, primary_key=True), |
… |
… |
class Command(LabelCommand):
|
57 | 69 | try: |
58 | 70 | curs.execute("\n".join(full_statement)) |
59 | 71 | except DatabaseError as e: |
60 | | transaction.rollback_unless_managed(using=db) |
| 72 | transaction.rollback_unless_managed(using=database) |
61 | 73 | raise CommandError( |
62 | 74 | "Cache table '%s' could not be created.\nThe error was: %s." % |
63 | 75 | (tablename, force_text(e))) |
64 | 76 | for statement in index_output: |
65 | 77 | curs.execute(statement) |
66 | | transaction.commit_unless_managed(using=db) |
| 78 | transaction.commit_unless_managed(using=database) |
| 79 | if self.verbosity > 1: |
| 80 | self.stdout.write("Cache table '%s' created." % tablename) |
diff --git a/django/db/backends/creation.py b/django/db/backends/creation.py
index 2baed62..573ab56 100644
a
|
b
|
class BaseDatabaseCreation(object):
|
303 | 303 | interactive=False, |
304 | 304 | database=self.connection.alias) |
305 | 305 | |
306 | | from django.core.cache import get_cache |
307 | | from django.core.cache.backends.db import BaseDatabaseCache |
308 | | for cache_alias in settings.CACHES: |
309 | | cache = get_cache(cache_alias) |
310 | | if isinstance(cache, BaseDatabaseCache): |
311 | | call_command('createcachetable', cache._table, |
312 | | database=self.connection.alias) |
| 306 | call_command('createcachetable', database=self.connection.alias) |
313 | 307 | |
314 | 308 | # Get a cursor (even though we don't need one yet). This has |
315 | 309 | # the side effect of initializing the test database. |
diff --git a/tests/regressiontests/cache/tests.py b/tests/regressiontests/cache/tests.py
index 42d0939..a4999f6 100644
a
|
b
|
def custom_key_func(key, key_prefix, version):
|
796 | 796 | return 'CUSTOM-' + '-'.join([key_prefix, str(version), key]) |
797 | 797 | |
798 | 798 | |
| 799 | @override_settings( |
| 800 | CACHES={ |
| 801 | 'default': { |
| 802 | 'BACKEND': 'django.core.cache.backends.db.DatabaseCache', |
| 803 | 'LOCATION': 'test cache table', |
| 804 | }, |
| 805 | }, |
| 806 | ) |
799 | 807 | class DBCacheTests(BaseCacheTests, TransactionTestCase): |
800 | 808 | backend_name = 'django.core.cache.backends.db.DatabaseCache' |
801 | 809 | |
802 | 810 | def setUp(self): |
803 | 811 | # Spaces are used in the table name to ensure quoting/escaping is working |
804 | 812 | self._table_name = 'test cache table' |
805 | | management.call_command('createcachetable', self._table_name, verbosity=0, interactive=False) |
| 813 | management.call_command('createcachetable', verbosity=0, interactive=False) |
806 | 814 | self.cache = get_cache(self.backend_name, LOCATION=self._table_name, OPTIONS={'MAX_ENTRIES': 30}) |
807 | 815 | self.prefix_cache = get_cache(self.backend_name, LOCATION=self._table_name, KEY_PREFIX='cacheprefix') |
808 | 816 | self.v2_cache = get_cache(self.backend_name, LOCATION=self._table_name, VERSION=2) |
… |
… |
class DBCacheTests(BaseCacheTests, TransactionTestCase):
|
831 | 839 | "Cache table 'test cache table' could not be created"): |
832 | 840 | management.call_command( |
833 | 841 | 'createcachetable', |
834 | | self._table_name, |
835 | 842 | verbosity=0, |
836 | 843 | interactive=False |
837 | 844 | ) |
… |
… |
class DBCacheRouter(object):
|
858 | 865 | return db == 'other' |
859 | 866 | |
860 | 867 | |
| 868 | @override_settings( |
| 869 | CACHES={ |
| 870 | 'default': { |
| 871 | 'BACKEND': 'django.core.cache.backends.db.DatabaseCache', |
| 872 | 'LOCATION': 'my_cache_table', |
| 873 | }, |
| 874 | }, |
| 875 | ) |
861 | 876 | class CreateCacheTableForDBCacheTests(TestCase): |
862 | 877 | multi_db = True |
863 | 878 | |
… |
… |
class CreateCacheTableForDBCacheTests(TestCase):
|
867 | 882 | router.routers = [DBCacheRouter()] |
868 | 883 | # cache table should not be created on 'default' |
869 | 884 | with self.assertNumQueries(0, using='default'): |
870 | | management.call_command('createcachetable', 'cache_table', |
| 885 | management.call_command('createcachetable', |
871 | 886 | database='default', |
872 | 887 | verbosity=0, interactive=False) |
873 | 888 | # cache table should be created on 'other' |
874 | 889 | # one query is used to create the table and another one the index |
875 | 890 | with self.assertNumQueries(2, using='other'): |
876 | | management.call_command('createcachetable', 'cache_table', |
| 891 | management.call_command('createcachetable', |
877 | 892 | database='other', |
878 | 893 | verbosity=0, interactive=False) |
879 | 894 | finally: |