sqlcreate.py 3.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. # -*- coding: utf-8 -*-
  2. import socket
  3. import sys
  4. from django.conf import settings
  5. from django.core.management.base import BaseCommand, CommandError
  6. from django_extensions.management.utils import signalcommand
  7. class Command(BaseCommand):
  8. help = """Generates the SQL to create your database for you, as specified in settings.py
  9. The envisioned use case is something like this:
  10. ./manage.py sqlcreate [--router=<routername>] | mysql -u <db_administrator> -p
  11. ./manage.py sqlcreate [--router=<routername>] | psql -U <db_administrator> -W"""
  12. requires_system_checks = False
  13. can_import_settings = True
  14. def add_arguments(self, parser):
  15. super().add_arguments(parser)
  16. parser.add_argument(
  17. '-R', '--router', action='store', dest='router', default='default',
  18. help='Use this router-database other then defined in settings.py'
  19. )
  20. parser.add_argument(
  21. '-D', '--drop', action='store_true', dest='drop', default=False,
  22. help='If given, includes commands to drop any existing user and database.'
  23. )
  24. @signalcommand
  25. def handle(self, *args, **options):
  26. router = options['router']
  27. dbinfo = settings.DATABASES.get(router)
  28. if dbinfo is None:
  29. raise CommandError("Unknown database router %s" % router)
  30. engine = dbinfo.get('ENGINE').split('.')[-1]
  31. dbuser = dbinfo.get('USER')
  32. dbpass = dbinfo.get('PASSWORD')
  33. dbname = dbinfo.get('NAME')
  34. dbhost = dbinfo.get('HOST')
  35. dbclient = socket.gethostname()
  36. # django settings file tells you that localhost should be specified by leaving
  37. # the DATABASE_HOST blank
  38. if not dbhost:
  39. dbhost = 'localhost'
  40. if engine == 'mysql':
  41. sys.stderr.write("""-- WARNING!: https://docs.djangoproject.com/en/dev/ref/databases/#collation-settings
  42. -- Please read this carefully! Collation will be set to utf8_bin to have case-sensitive data.
  43. """)
  44. print("CREATE DATABASE %s CHARACTER SET utf8 COLLATE utf8_bin;" % dbname)
  45. print("GRANT ALL PRIVILEGES ON %s.* to '%s'@'%s' identified by '%s';" % (
  46. dbname, dbuser, dbclient, dbpass
  47. ))
  48. elif engine in ('postgresql', 'postgresql_psycopg2', 'postgis'):
  49. if options['drop']:
  50. print("DROP DATABASE IF EXISTS %s;" % (dbname,))
  51. print("DROP USER IF EXISTS %s;" % (dbuser,))
  52. print("CREATE USER %s WITH ENCRYPTED PASSWORD '%s' CREATEDB;" % (dbuser, dbpass))
  53. print("CREATE DATABASE %s WITH ENCODING 'UTF-8' OWNER \"%s\";" % (dbname, dbuser))
  54. print("GRANT ALL PRIVILEGES ON DATABASE %s TO %s;" % (dbname, dbuser))
  55. elif engine == 'sqlite3':
  56. sys.stderr.write("-- manage.py syncdb will automatically create a sqlite3 database file.\n")
  57. else:
  58. # CREATE DATABASE is not SQL standard, but seems to be supported by most.
  59. sys.stderr.write("-- Don't know how to handle '%s' falling back to SQL.\n" % engine)
  60. print("CREATE DATABASE %s;" % dbname)
  61. print("GRANT ALL PRIVILEGES ON DATABASE %s to %s;" % (dbname, dbuser))