You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

createcachetable.py 4.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. from django.conf import settings
  2. from django.core.cache import caches
  3. from django.core.cache.backends.db import BaseDatabaseCache
  4. from django.core.management.base import BaseCommand, CommandError
  5. from django.db import (
  6. DEFAULT_DB_ALIAS, connections, models, router, transaction,
  7. )
  8. from django.db.utils import DatabaseError
  9. class Command(BaseCommand):
  10. help = "Creates the tables needed to use the SQL cache backend."
  11. requires_system_checks = False
  12. def add_arguments(self, parser):
  13. parser.add_argument(
  14. 'args', metavar='table_name', nargs='*',
  15. help='Optional table names. Otherwise, settings.CACHES is used to find cache tables.',
  16. )
  17. parser.add_argument(
  18. '--database',
  19. default=DEFAULT_DB_ALIAS,
  20. help='Nominates a database onto which the cache tables will be '
  21. 'installed. Defaults to the "default" database.',
  22. )
  23. parser.add_argument(
  24. '--dry-run', action='store_true',
  25. help='Does not create the table, just prints the SQL that would be run.',
  26. )
  27. def handle(self, *tablenames, **options):
  28. db = options['database']
  29. self.verbosity = options['verbosity']
  30. dry_run = options['dry_run']
  31. if tablenames:
  32. # Legacy behavior, tablename specified as argument
  33. for tablename in tablenames:
  34. self.create_table(db, tablename, dry_run)
  35. else:
  36. for cache_alias in settings.CACHES:
  37. cache = caches[cache_alias]
  38. if isinstance(cache, BaseDatabaseCache):
  39. self.create_table(db, cache._table, dry_run)
  40. def create_table(self, database, tablename, dry_run):
  41. cache = BaseDatabaseCache(tablename, {})
  42. if not router.allow_migrate_model(database, cache.cache_model_class):
  43. return
  44. connection = connections[database]
  45. if tablename in connection.introspection.table_names():
  46. if self.verbosity > 0:
  47. self.stdout.write("Cache table '%s' already exists." % tablename)
  48. return
  49. fields = (
  50. # "key" is a reserved word in MySQL, so use "cache_key" instead.
  51. models.CharField(name='cache_key', max_length=255, unique=True, primary_key=True),
  52. models.TextField(name='value'),
  53. models.DateTimeField(name='expires', db_index=True),
  54. )
  55. table_output = []
  56. index_output = []
  57. qn = connection.ops.quote_name
  58. for f in fields:
  59. field_output = [
  60. qn(f.name),
  61. f.db_type(connection=connection),
  62. '%sNULL' % ('NOT ' if not f.null else ''),
  63. ]
  64. if f.primary_key:
  65. field_output.append("PRIMARY KEY")
  66. elif f.unique:
  67. field_output.append("UNIQUE")
  68. if f.db_index:
  69. unique = "UNIQUE " if f.unique else ""
  70. index_output.append(
  71. "CREATE %sINDEX %s ON %s (%s);" %
  72. (unique, qn('%s_%s' % (tablename, f.name)), qn(tablename), qn(f.name))
  73. )
  74. table_output.append(" ".join(field_output))
  75. full_statement = ["CREATE TABLE %s (" % qn(tablename)]
  76. for i, line in enumerate(table_output):
  77. full_statement.append(' %s%s' % (line, ',' if i < len(table_output) - 1 else ''))
  78. full_statement.append(');')
  79. full_statement = "\n".join(full_statement)
  80. if dry_run:
  81. self.stdout.write(full_statement)
  82. for statement in index_output:
  83. self.stdout.write(statement)
  84. return
  85. with transaction.atomic(using=database, savepoint=connection.features.can_rollback_ddl):
  86. with connection.cursor() as curs:
  87. try:
  88. curs.execute(full_statement)
  89. except DatabaseError as e:
  90. raise CommandError(
  91. "Cache table '%s' could not be created.\nThe error was: %s." %
  92. (tablename, e))
  93. for statement in index_output:
  94. curs.execute(statement)
  95. if self.verbosity > 1:
  96. self.stdout.write("Cache table '%s' created." % tablename)