1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
|
# -*- coding: utf-8 -*-
import socket
import sys
import warnings
from typing import List
from django.conf import settings
from django.core.management.base import BaseCommand, CommandError
from django.db import DEFAULT_DB_ALIAS
from django_extensions.management.utils import signalcommand
from django_extensions.utils.deprecation import RemovedInNextVersionWarning
from django_extensions.settings import SQLITE_ENGINES, POSTGRESQL_ENGINES, MYSQL_ENGINES
class Command(BaseCommand):
help = """Generates the SQL to create your database for you, as specified in settings.py
The envisioned use case is something like this:
./manage.py sqlcreate [--database=<databasename>] | mysql -u <db_administrator> -p
./manage.py sqlcreate [--database=<databasname>] | psql -U <db_administrator> -W
""" # noqa: E501
requires_system_checks: List[str] = []
can_import_settings = True
def add_arguments(self, parser):
super().add_arguments(parser)
parser.add_argument(
"-R",
"--router",
action="store",
dest="router",
default=DEFAULT_DB_ALIAS,
help="Use this router-database other then defined in settings.py",
)
parser.add_argument(
"--database",
default=DEFAULT_DB_ALIAS,
help=(
"Nominates a database to run command for. "
'Defaults to the "%s" database.'
)
% DEFAULT_DB_ALIAS,
)
parser.add_argument(
"-D",
"--drop",
action="store_true",
dest="drop",
default=False,
help="If given, includes commands to drop any existing user and database.",
)
@signalcommand
def handle(self, *args, **options):
database = options["database"]
if options["router"] != DEFAULT_DB_ALIAS:
warnings.warn(
"--router is deprecated. You should use --database.",
RemovedInNextVersionWarning,
stacklevel=2,
)
database = options["router"]
dbinfo = settings.DATABASES.get(database)
if dbinfo is None:
raise CommandError("Unknown database %s" % database)
engine = dbinfo.get("ENGINE")
dbuser = dbinfo.get("USER")
dbpass = dbinfo.get("PASSWORD")
dbname = dbinfo.get("NAME")
dbhost = dbinfo.get("HOST")
dbclient = socket.gethostname()
# django settings file tells you that localhost should be specified by leaving
# the DATABASE_HOST blank
if not dbhost:
dbhost = "localhost"
if engine in SQLITE_ENGINES:
sys.stderr.write(
"-- manage.py migrate will automatically create a sqlite3 database file.\n" # noqa: E501
)
elif engine in MYSQL_ENGINES:
sys.stderr.write(
"""-- WARNING!: https://docs.djangoproject.com/en/dev/ref/databases/#collation-settings
-- Please read this carefully! Collation will be set to utf8_bin to have case-sensitive data.
""" # noqa: E501
)
print("CREATE DATABASE %s CHARACTER SET utf8 COLLATE utf8_bin;" % dbname)
print(
"GRANT ALL PRIVILEGES ON %s.* to '%s'@'%s' identified by '%s';"
% (dbname, dbuser, dbclient, dbpass)
)
elif engine in POSTGRESQL_ENGINES:
if options["drop"]:
print("DROP DATABASE IF EXISTS %s;" % (dbname,))
if dbuser:
print("DROP USER IF EXISTS %s;" % (dbuser,))
if dbuser and dbpass:
print(
"CREATE USER %s WITH ENCRYPTED PASSWORD '%s' CREATEDB;"
% (dbuser, dbpass)
)
print(
"CREATE DATABASE %s WITH ENCODING 'UTF-8' OWNER \"%s\";"
% (dbname, dbuser)
)
print("GRANT ALL PRIVILEGES ON DATABASE %s TO %s;" % (dbname, dbuser))
else:
print(
"-- Assuming that unix domain socket connection mode is being used because\n" # noqa: E501
"-- USER or PASSWORD are blank in Django DATABASES configuration."
)
print("CREATE DATABASE %s WITH ENCODING 'UTF-8';" % (dbname,))
else:
# CREATE DATABASE is not SQL standard, but seems to be supported by most.
sys.stderr.write(
"-- Don't know how to handle '%s' falling back to SQL.\n" % engine
)
print("CREATE DATABASE %s;" % dbname)
print("GRANT ALL PRIVILEGES ON DATABASE %s to %s;" % (dbname, dbuser))
|