Fixed #24560 -- Added a --dry-run mode to the createcachetable command.

This commit is contained in:
Adam Chainz 2015-04-01 22:33:27 +01:00 committed by Tim Graham
parent 727e40c879
commit 5564d0f2ee
5 changed files with 40 additions and 4 deletions

View File

@ -22,21 +22,25 @@ class Command(BaseCommand):
default=DEFAULT_DB_ALIAS, default=DEFAULT_DB_ALIAS,
help='Nominates a database onto which the cache tables will be ' help='Nominates a database onto which the cache tables will be '
'installed. Defaults to the "default" database.') 'installed. Defaults to the "default" database.')
parser.add_argument('--dry-run', action='store_true', dest='dry_run',
help='Does not create the table, just prints the SQL that would '
'be run.')
def handle(self, *tablenames, **options): def handle(self, *tablenames, **options):
db = options.get('database') db = options.get('database')
self.verbosity = int(options.get('verbosity')) self.verbosity = int(options.get('verbosity'))
dry_run = options.get('dry_run')
if len(tablenames): if len(tablenames):
# Legacy behavior, tablename specified as argument # Legacy behavior, tablename specified as argument
for tablename in tablenames: for tablename in tablenames:
self.create_table(db, tablename) self.create_table(db, tablename, dry_run)
else: else:
for cache_alias in settings.CACHES: for cache_alias in settings.CACHES:
cache = caches[cache_alias] cache = caches[cache_alias]
if isinstance(cache, BaseDatabaseCache): if isinstance(cache, BaseDatabaseCache):
self.create_table(db, cache._table) self.create_table(db, cache._table, dry_run)
def create_table(self, database, tablename): def create_table(self, database, tablename, dry_run):
cache = BaseDatabaseCache(tablename, {}) cache = BaseDatabaseCache(tablename, {})
if not router.allow_migrate_model(database, cache.cache_model_class): if not router.allow_migrate_model(database, cache.cache_model_class):
return return
@ -74,11 +78,19 @@ class Command(BaseCommand):
full_statement.append(' %s%s' % (line, ',' if i < len(table_output) - 1 else '')) full_statement.append(' %s%s' % (line, ',' if i < len(table_output) - 1 else ''))
full_statement.append(');') full_statement.append(');')
full_statement = "\n".join(full_statement)
if dry_run:
self.stdout.write(full_statement)
for statement in index_output:
self.stdout.write(statement)
return
with transaction.atomic(using=database, with transaction.atomic(using=database,
savepoint=connection.features.can_rollback_ddl): savepoint=connection.features.can_rollback_ddl):
with connection.cursor() as curs: with connection.cursor() as curs:
try: try:
curs.execute("\n".join(full_statement)) curs.execute(full_statement)
except DatabaseError as e: except DatabaseError as e:
raise CommandError( raise CommandError(
"Cache table '%s' could not be created.\nThe error was: %s." % "Cache table '%s' could not be created.\nThe error was: %s." %

View File

@ -189,6 +189,13 @@ The :djadminopt:`--database` option can be used to specify the database
onto which the cache table will be installed, but since this information is onto which the cache table will be installed, but since this information is
pulled from your settings by default, it's typically not needed. pulled from your settings by default, it's typically not needed.
The :djadminopt:`--dry-run` option will print the SQL that would be run without
actually running it, so you can customize it or use the migrations framework.
.. versionchanged:: 1.9
The ``--dry-run`` option was added.
dbshell dbshell
------- -------

View File

@ -166,6 +166,9 @@ Management Commands
* The :djadmin:`dumpdata` command output is now deterministically ordered. * The :djadmin:`dumpdata` command output is now deterministically ordered.
* The :djadmin:`createcachetable` command now has a ``--dry-run`` flag to
print out the SQL rather than execute it.
Models Models
^^^^^^ ^^^^^^

View File

@ -206,6 +206,9 @@ If you are using multiple databases, :djadmin:`createcachetable` observes the
Like :djadmin:`migrate`, :djadmin:`createcachetable` won't touch an existing Like :djadmin:`migrate`, :djadmin:`createcachetable` won't touch an existing
table. It will only create missing tables. table. It will only create missing tables.
To print the SQL that would be run, rather than run it, use the
:djadminopt:`--dry-run` option.
Multiple databases Multiple databases
~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~

11
tests/cache/tests.py vendored
View File

@ -943,6 +943,17 @@ class DBCacheTests(BaseCacheTests, TransactionTestCase):
self.assertEqual(out.getvalue(), self.assertEqual(out.getvalue(),
"Cache table 'test cache table' already exists.\n" * len(settings.CACHES)) "Cache table 'test cache table' already exists.\n" * len(settings.CACHES))
@override_settings(CACHES=caches_setting_for_tests(
BACKEND='django.core.cache.backends.db.DatabaseCache',
# Use another table name to avoid the 'table already exists' message.
LOCATION='createcachetable_dry_run_mode'
))
def test_createcachetable_dry_run_mode(self):
out = six.StringIO()
management.call_command('createcachetable', dry_run=True, stdout=out)
output = out.getvalue()
self.assertTrue(output.startswith("CREATE TABLE"))
def test_createcachetable_with_table_argument(self): def test_createcachetable_with_table_argument(self):
""" """
Delete and recreate cache table with legacy behavior (explicitly Delete and recreate cache table with legacy behavior (explicitly