Exemple #1
0
def call_command(name, *args, **options):
    """
    Calls the given command, with the given options and args/kwargs.

    This is the primary API you should use for calling specific commands.

    Some examples:
        call_command('syncdb')
        call_command('shell', plain=True)
        call_command('sqlall', 'myapp')
    """
    # Load the command object.
    try:
        app_name = get_commands()[name]
        if isinstance(app_name, BaseCommand):
            # If the command is already loaded, use it directly.
            klass = app_name
        else:
            klass = load_command_class(app_name, name)
    except KeyError:
        raise CommandError("Unknown command: %r" % name)

    # Grab out a list of defaults from the options. optparse does this for us
    # when the script runs from the command line, but since call_command can
    # be called programatically, we need to simulate the loading and handling
    # of defaults (see #10080 for details).
    defaults = dict([(o.dest, o.default) for o in klass.option_list
                     if o.default is not NO_DEFAULT])
    defaults.update(options)

    return klass.execute(*args, **defaults)
Exemple #2
0
    def handle_label(self, project_name, **options):
        # Determine the project_name a bit naively -- by looking at the name of
        # the parent directory.
        directory = os.getcwd()

        # Check that the project_name cannot be imported.
        try:
            import_module(project_name)
        except ImportError:
            pass
        else:
            raise CommandError(
                "%r conflicts with the name of an existing Python module and cannot be used as a project name. Please try another name."
                % project_name)

        copy_helper(self.style, 'project', project_name, directory)

        # Create a random SECRET_KEY hash, and put it in the main settings.
        main_settings_file = os.path.join(directory, project_name,
                                          'settings.py')
        settings_contents = open(main_settings_file, 'r').read()
        fp = open(main_settings_file, 'w')
        secret_key = ''.join([
            choice('abcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*(-_=+)')
            for i in range(50)
        ])
        settings_contents = re.sub(r"(?<=SECRET_KEY = ')'", secret_key + "'",
                                   settings_contents)
        fp.write(settings_contents)
        fp.close()
Exemple #3
0
    def handle_app(self, app, **options):
        using = options.get('database', DEFAULT_DB_ALIAS)
        connection = connections[using]

        app_name = app.__name__.split('.')[-2]
        self.style = no_style()

        sql_list = sql_reset(app, self.style, connection)

        if options.get('interactive'):
            confirm = raw_input("""
You have requested a database reset.
This will IRREVERSIBLY DESTROY any data for
the "%s" application in the database "%s".
Are you sure you want to do this?

Type 'yes' to continue, or 'no' to cancel: """ % (app_name, connection.settings_dict['NAME']))
        else:
            confirm = 'yes'

        if confirm == 'yes':
            try:
                cursor = connection.cursor()
                for sql in sql_list:
                    cursor.execute(sql)
            except Exception, e:
                transaction.rollback_unless_managed()
                raise CommandError("""Error: %s couldn't be reset. Possible reasons:
  * The database isn't running or isn't configured correctly.
  * At least one of the database tables doesn't exist.
  * The SQL was invalid.
Hint: Look at the output of 'django-admin.py sqlreset %s'. That's the SQL this command wasn't able to run.
The full error: %s""" % (app_name, app_name, e))
            transaction.commit_unless_managed()
Exemple #4
0
    def handle(self, *args, **options):
        if len(args) != 0:
            raise CommandError("Command doesn't accept any arguments")

        locale = options.get('locale')
        domain = options.get('domain')
        verbosity = int(options.get('verbosity'))
        process_all = options.get('all')
        extensions = options.get('extensions')
        symlinks = options.get('symlinks')
        ignore_patterns = options.get('ignore_patterns')
        if options.get('use_default_ignore_patterns'):
            ignore_patterns += ['CVS', '.*', '*~']
        ignore_patterns = list(set(ignore_patterns))

        if domain == 'djangojs':
            extensions = handle_extensions(extensions or ['js'])
        else:
            extensions = handle_extensions(extensions or ['html'])

        if verbosity > 1:
            sys.stdout.write('examining files with the extensions: %s\n' %
                             get_text_list(list(extensions), 'and'))

        make_messages(locale, domain, verbosity, process_all, extensions,
                      symlinks, ignore_patterns)
Exemple #5
0
 def handle_noargs(self, **options):
     try:
         for line in self.handle_inspection(options):
             self.stdout.write("%s\n" % line)
     except NotImplementedError:
         raise CommandError(
             "Database inspection isn't supported for the currently selected database backend."
         )
Exemple #6
0
    def handle_noargs(self, **options):
        db = options.get('database', DEFAULT_DB_ALIAS)
        connection = connections[db]
        verbosity = int(options.get('verbosity', 1))
        interactive = options.get('interactive')

        self.style = no_style()

        # Import the 'management' module within each installed app, to register
        # dispatcher events.
        for app_name in settings.INSTALLED_APPS:
            try:
                import_module('.management', app_name)
            except ImportError:
                pass

        sql_list = sql_flush(self.style, connection, only_django=True)

        if interactive:
            confirm = raw_input("""You have requested a flush of the database.
This will IRREVERSIBLY DESTROY all data currently in the %r database,
and return each table to the state it was in after syncdb.
Are you sure you want to do this?

    Type 'yes' to continue, or 'no' to cancel: """ % connection.settings_dict['NAME'])
        else:
            confirm = 'yes'

        if confirm == 'yes':
            try:
                cursor = connection.cursor()
                for sql in sql_list:
                    cursor.execute(sql)
            except Exception, e:
                transaction.rollback_unless_managed(using=db)
                raise CommandError("""Database %s couldn't be flushed. Possible reasons:
  * The database isn't running or isn't configured correctly.
  * At least one of the expected database tables doesn't exist.
  * The SQL was invalid.
Hint: Look at the output of 'django-admin.py sqlflush'. That's the SQL this command wasn't able to run.
The full error: %s""" % (connection.settings_dict['NAME'], e))
            transaction.commit_unless_managed(using=db)

            # Emit the post sync signal. This allows individual
            # applications to respond as if the database had been
            # sync'd from scratch.
            all_models = []
            for app in models.get_apps():
                all_models.extend([
                    m for m in models.get_models(app, include_auto_created=True)
                    if router.allow_syncdb(db, m)
                ])
            emit_post_sync_signal(all_models, verbosity, interactive, db)

            # Reinstall the initial_data fixture.
            kwargs = options.copy()
            kwargs['database'] = db
            call_command('loaddata', 'initial_data', **kwargs)
Exemple #7
0
 def handle(self, **options):
     connection = connections[options.get('database', DEFAULT_DB_ALIAS)]
     try:
         connection.client.runshell()
     except OSError:
         # Note that we're assuming OSError means that the client program
         # isn't installed. There's a possibility OSError would be raised
         # for some other reason, in which case this error message would be
         # inaccurate. Still, this message catches the common case.
         raise CommandError(
             'You appear not to have the %r program installed or on your path.'
             % connection.client.executable_name)
Exemple #8
0
def compile_messages(stderr, locale=None):
    basedirs = [os.path.join('conf', 'locale'), 'locale']
    if os.environ.get('DJANGO_SETTINGS_MODULE'):
        from google.appengine._internal.django.conf import settings
        basedirs.extend(settings.LOCALE_PATHS)

    # Gather existing directories.
    basedirs = set(map(os.path.abspath, filter(os.path.isdir, basedirs)))

    if not basedirs:
        raise CommandError(
            "This script should be run from the Django SVN tree or your project or app tree, or with the settings module specified."
        )

    for basedir in basedirs:
        if locale:
            basedir = os.path.join(basedir, locale, 'LC_MESSAGES')
        for dirpath, dirnames, filenames in os.walk(basedir):
            for f in filenames:
                if f.endswith('.po'):
                    stderr.write('processing file %s in %s\n' % (f, dirpath))
                    fn = os.path.join(dirpath, f)
                    if has_bom(fn):
                        raise CommandError(
                            "The %s file has a BOM (Byte Order Mark). Django only supports .po files encoded in UTF-8 and without any BOM."
                            % fn)
                    pf = os.path.splitext(fn)[0]
                    # Store the names of the .mo and .po files in an environment
                    # variable, rather than doing a string replacement into the
                    # command, so that we can take advantage of shell quoting, to
                    # quote any malicious characters/escaping.
                    # See http://cyberelk.net/tim/articles/cmdline/ar01s02.html
                    os.environ['djangocompilemo'] = pf + '.mo'
                    os.environ['djangocompilepo'] = pf + '.po'
                    if sys.platform == 'win32':  # Different shell-variable syntax
                        cmd = 'msgfmt --check-format -o "%djangocompilemo%" "%djangocompilepo%"'
                    else:
                        cmd = 'msgfmt --check-format -o "$djangocompilemo" "$djangocompilepo"'
                    os.system(cmd)
Exemple #9
0
    def handle_label(self, app_name, directory=None, **options):
        if directory is None:
            directory = os.getcwd()

        # Determine the project_name by using the basename of directory,
        # which should be the full path of the project directory (or the
        # current directory if no directory was passed).
        project_name = os.path.basename(directory)
        if app_name == project_name:
            raise CommandError("You cannot create an app with the same name"
                               " (%r) as your project." % app_name)

        # Check that the app_name cannot be imported.
        try:
            import_module(app_name)
        except ImportError:
            pass
        else:
            raise CommandError(
                "%r conflicts with the name of an existing Python module and cannot be used as an app name. Please try another name."
                % app_name)

        copy_helper(self.style, 'app', app_name, directory, project_name)
Exemple #10
0
def sql_create(app, style, connection):
    "Returns a list of the CREATE TABLE SQL statements for the given app."

    if connection.settings_dict['ENGINE'] == 'django.db.backends.dummy':
        # This must be the "dummy" database backend, which means the user
        # hasn't set ENGINE for the databse.
        raise CommandError(
            "Django doesn't know which syntax to use for your SQL statements,\n"
            +
            "because you haven't specified the ENGINE setting for the database.\n"
            +
            "Edit your settings file and change DATBASES['default']['ENGINE'] to something like\n"
            + "'django.db.backends.postgresql' or 'django.db.backends.mysql'.")

    # Get installed models, so we generate REFERENCES right.
    # We trim models from the current app so that the sqlreset command does not
    # generate invalid SQL (leaving models out of known_models is harmless, so
    # we can be conservative).
    app_models = models.get_models(app, include_auto_created=True)
    final_output = []
    tables = connection.introspection.table_names()
    known_models = set([
        model for model in connection.introspection.installed_models(tables)
        if model not in app_models
    ])
    pending_references = {}

    for model in app_models:
        output, references = connection.creation.sql_create_model(
            model, style, known_models)
        final_output.extend(output)
        for refto, refs in references.items():
            pending_references.setdefault(refto, []).extend(refs)
            if refto in known_models:
                final_output.extend(
                    connection.creation.sql_for_pending_references(
                        refto, style, pending_references))
        final_output.extend(
            connection.creation.sql_for_pending_references(
                model, style, pending_references))
        # Keep track of the fact that we've created the table for this model.
        known_models.add(model)

    # Handle references to tables that are from other apps
    # but don't exist physically.
    not_installed_models = set(pending_references.keys())
    if not_installed_models:
        alter_sql = []
        for model in not_installed_models:
            alter_sql.extend([
                '-- ' + sql
                for sql in connection.creation.sql_for_pending_references(
                    model, style, pending_references)
            ])
        if alter_sql:
            final_output.append(
                '-- The following references should be added but depend on non-existent tables:'
            )
            final_output.extend(alter_sql)

    return final_output
Exemple #11
0
def sort_dependencies(app_list):
    """Sort a list of app,modellist pairs into a single list of models.

    The single list of models is sorted so that any model with a natural key
    is serialized before a normal model, and any model with a natural key
    dependency has it's dependencies serialized first.
    """
    from google.appengine._internal.django.db.models import get_model, get_models
    # Process the list of models, and get the list of dependencies
    model_dependencies = []
    models = set()
    for app, model_list in app_list:
        if model_list is None:
            model_list = get_models(app)

        for model in model_list:
            models.add(model)
            # Add any explicitly defined dependencies
            if hasattr(model, 'natural_key'):
                deps = getattr(model.natural_key, 'dependencies', [])
                if deps:
                    deps = [get_model(*d.split('.')) for d in deps]
            else:
                deps = []

            # Now add a dependency for any FK or M2M relation with
            # a model that defines a natural key
            for field in model._meta.fields:
                if hasattr(field.rel, 'to'):
                    rel_model = field.rel.to
                    if hasattr(rel_model, 'natural_key'):
                        deps.append(rel_model)
            for field in model._meta.many_to_many:
                rel_model = field.rel.to
                if hasattr(rel_model, 'natural_key'):
                    deps.append(rel_model)
            model_dependencies.append((model, deps))

    model_dependencies.reverse()
    # Now sort the models to ensure that dependencies are met. This
    # is done by repeatedly iterating over the input list of models.
    # If all the dependencies of a given model are in the final list,
    # that model is promoted to the end of the final list. This process
    # continues until the input list is empty, or we do a full iteration
    # over the input models without promoting a model to the final list.
    # If we do a full iteration without a promotion, that means there are
    # circular dependencies in the list.
    model_list = []
    while model_dependencies:
        skipped = []
        changed = False
        while model_dependencies:
            model, deps = model_dependencies.pop()

            # If all of the models in the dependency list are either already
            # on the final model list, or not on the original serialization list,
            # then we've found another model with all it's dependencies satisfied.
            found = True
            for candidate in ((d not in models or d in model_list) for d in deps):
                if not candidate:
                    found = False
            if found:
                model_list.append(model)
                changed = True
            else:
                skipped.append((model, deps))
        if not changed:
            raise CommandError("Can't resolve dependencies for %s in serialized app list." %
                ', '.join('%s.%s' % (model._meta.app_label, model._meta.object_name)
                for model, deps in sorted(skipped, key=lambda obj: obj[0].__name__))
            )
        model_dependencies = skipped

    return model_list
Exemple #12
0
    def handle(self, *app_labels, **options):
        from google.appengine._internal.django.db.models import get_app, get_apps, get_models, get_model

        format = options.get('format','json')
        indent = options.get('indent',None)
        using = options.get('database', DEFAULT_DB_ALIAS)
        connection = connections[using]
        exclude = options.get('exclude',[])
        show_traceback = options.get('traceback', False)
        use_natural_keys = options.get('use_natural_keys', False)

        excluded_apps = set(get_app(app_label) for app_label in exclude)

        if len(app_labels) == 0:
            app_list = SortedDict((app, None) for app in get_apps() if app not in excluded_apps)
        else:
            app_list = SortedDict()
            for label in app_labels:
                try:
                    app_label, model_label = label.split('.')
                    try:
                        app = get_app(app_label)
                    except ImproperlyConfigured:
                        raise CommandError("Unknown application: %s" % app_label)

                    model = get_model(app_label, model_label)
                    if model is None:
                        raise CommandError("Unknown model: %s.%s" % (app_label, model_label))

                    if app in app_list.keys():
                        if app_list[app] and model not in app_list[app]:
                            app_list[app].append(model)
                    else:
                        app_list[app] = [model]
                except ValueError:
                    # This is just an app - no model qualifier
                    app_label = label
                    try:
                        app = get_app(app_label)
                    except ImproperlyConfigured:
                        raise CommandError("Unknown application: %s" % app_label)
                    app_list[app] = None

        # Check that the serialization format exists; this is a shortcut to
        # avoid collating all the objects and _then_ failing.
        if format not in serializers.get_public_serializer_formats():
            raise CommandError("Unknown serialization format: %s" % format)

        try:
            serializers.get_serializer(format)
        except KeyError:
            raise CommandError("Unknown serialization format: %s" % format)

        # Now collate the objects to be serialized.
        objects = []
        for model in sort_dependencies(app_list.items()):
            if not model._meta.proxy and router.allow_syncdb(using, model):
                objects.extend(model._default_manager.using(using).all())

        try:
            return serializers.serialize(format, objects, indent=indent,
                        use_natural_keys=use_natural_keys)
        except Exception, e:
            if show_traceback:
                raise
            raise CommandError("Unable to serialize database: %s" % e)
Exemple #13
0
def make_messages(locale=None, domain='django', verbosity='1', all=False,
        extensions=None, symlinks=False, ignore_patterns=[]):
    """
    Uses the locale directory from the Django SVN tree or an application/
    project to process all
    """
    # Need to ensure that the i18n framework is enabled
    from google.appengine._internal.django.conf import settings
    if settings.configured:
        settings.USE_I18N = True
    else:
        settings.configure(USE_I18N = True)

    from google.appengine._internal.django.utils.translation import templatize

    invoked_for_django = False
    if os.path.isdir(os.path.join('conf', 'locale')):
        localedir = os.path.abspath(os.path.join('conf', 'locale'))
        invoked_for_django = True
    elif os.path.isdir('locale'):
        localedir = os.path.abspath('locale')
    else:
        raise CommandError("This script should be run from the Django SVN tree or your project or app tree. If you did indeed run it from the SVN checkout or your project or application, maybe you are just missing the conf/locale (in the django tree) or locale (for project and application) directory? It is not created automatically, you have to create it by hand if you want to enable i18n for your project or application.")

    if domain not in ('django', 'djangojs'):
        raise CommandError("currently makemessages only supports domains 'django' and 'djangojs'")

    if (locale is None and not all) or domain is None:
        # backwards compatible error message
        if not sys.argv[0].endswith("make-messages.py"):
            message = "Type '%s help %s' for usage.\n" % (os.path.basename(sys.argv[0]), sys.argv[1])
        else:
            message = "usage: make-messages.py -l <language>\n   or: make-messages.py -a\n"
        raise CommandError(message)

    # We require gettext version 0.15 or newer.
    output = _popen('xgettext --version')[0]
    match = re.search(r'(?P<major>\d+)\.(?P<minor>\d+)', output)
    if match:
        xversion = (int(match.group('major')), int(match.group('minor')))
        if xversion < (0, 15):
            raise CommandError("Django internationalization requires GNU gettext 0.15 or newer. You are using version %s, please upgrade your gettext toolset." % match.group())

    languages = []
    if locale is not None:
        languages.append(locale)
    elif all:
        locale_dirs = list(filter(os.path.isdir, glob.glob('%s/*' % localedir)))
        languages = [os.path.basename(l) for l in locale_dirs]

    for locale in languages:
        if verbosity > 0:
            print("processing language", locale)
        basedir = os.path.join(localedir, locale, 'LC_MESSAGES')
        if not os.path.isdir(basedir):
            os.makedirs(basedir)

        pofile = os.path.join(basedir, '%s.po' % domain)
        potfile = os.path.join(basedir, '%s.pot' % domain)

        if os.path.exists(potfile):
            os.unlink(potfile)

        for dirpath, file in find_files(".", ignore_patterns, verbosity, symlinks=symlinks):
            file_base, file_ext = os.path.splitext(file)
            if domain == 'djangojs' and file_ext in extensions:
                if verbosity > 1:
                    sys.stdout.write('processing file %s in %s\n' % (file, dirpath))
                src = open(os.path.join(dirpath, file), "rU").read()
                src = pythonize_re.sub('\n#', src)
                thefile = '%s.py' % file
                f = open(os.path.join(dirpath, thefile), "w")
                try:
                    f.write(src)
                finally:
                    f.close()
                cmd = 'xgettext -d %s -L Perl --keyword=gettext_noop --keyword=gettext_lazy --keyword=ngettext_lazy:1,2 --from-code UTF-8 -o - "%s"' % (domain, os.path.join(dirpath, thefile))
                msgs, errors = _popen(cmd)
                if errors:
                    raise CommandError("errors happened while running xgettext on %s\n%s" % (file, errors))
                old = '#: '+os.path.join(dirpath, thefile)[2:]
                new = '#: '+os.path.join(dirpath, file)[2:]
                msgs = msgs.replace(old, new)
                if os.path.exists(potfile):
                    # Strip the header
                    msgs = '\n'.join(dropwhile(len, msgs.split('\n')))
                else:
                    msgs = msgs.replace('charset=CHARSET', 'charset=UTF-8')
                if msgs:
                    f = open(potfile, 'ab')
                    try:
                        f.write(msgs)
                    finally:
                        f.close()
                os.unlink(os.path.join(dirpath, thefile))
            elif domain == 'django' and (file_ext == '.py' or file_ext in extensions):
                thefile = file
                if file_ext in extensions:
                    src = open(os.path.join(dirpath, file), "rU").read()
                    thefile = '%s.py' % file
                    try:
                        f = open(os.path.join(dirpath, thefile), "w")
                        try:
                            f.write(templatize(src))
                        finally:
                            f.close()
                    except SyntaxError as msg:
                        msg = "%s (file: %s)" % (msg, os.path.join(dirpath, file))
                        raise SyntaxError(msg)
                if verbosity > 1:
                    sys.stdout.write('processing file %s in %s\n' % (file, dirpath))
                cmd = 'xgettext -d %s -L Python --keyword=gettext_noop --keyword=gettext_lazy --keyword=ngettext_lazy:1,2 --keyword=ugettext_noop --keyword=ugettext_lazy --keyword=ungettext_lazy:1,2 --from-code UTF-8 -o - "%s"' % (
                    domain, os.path.join(dirpath, thefile))
                msgs, errors = _popen(cmd)
                if errors:
                    raise CommandError("errors happened while running xgettext on %s\n%s" % (file, errors))

                if thefile != file:
                    old = '#: '+os.path.join(dirpath, thefile)[2:]
                    new = '#: '+os.path.join(dirpath, file)[2:]
                    msgs = msgs.replace(old, new)
                if os.path.exists(potfile):
                    # Strip the header
                    msgs = '\n'.join(dropwhile(len, msgs.split('\n')))
                else:
                    msgs = msgs.replace('charset=CHARSET', 'charset=UTF-8')
                if msgs:
                    f = open(potfile, 'ab')
                    try:
                        f.write(msgs)
                    finally:
                        f.close()
                if thefile != file:
                    os.unlink(os.path.join(dirpath, thefile))

        if os.path.exists(potfile):
            msgs, errors = _popen('msguniq --to-code=utf-8 "%s"' % potfile)
            if errors:
                raise CommandError("errors happened while running msguniq\n%s" % errors)
            f = open(potfile, 'w')
            try:
                f.write(msgs)
            finally:
                f.close()
            if os.path.exists(pofile):
                msgs, errors = _popen('msgmerge -q "%s" "%s"' % (pofile, potfile))
                if errors:
                    raise CommandError("errors happened while running msgmerge\n%s" % errors)
            elif not invoked_for_django:
                msgs = copy_plural_forms(msgs, locale, domain, verbosity)
            f = open(pofile, 'wb')
            try:
                f.write(msgs)
            finally:
                f.close()
            os.unlink(potfile)
Exemple #14
0
    def handle(self, addrport='', *args, **options):
        import django
        from google.appengine._internal.django.core.servers.basehttp import run, AdminMediaHandler, WSGIServerException
        from google.appengine._internal.django.core.handlers.wsgi import WSGIHandler
        if args:
            raise CommandError('Usage is runserver %s' % self.args)
        if not addrport:
            addr = ''
            port = '8000'
        else:
            try:
                addr, port = addrport.split(':')
            except ValueError:
                addr, port = '', addrport
        if not addr:
            addr = '127.0.0.1'

        if not port.isdigit():
            raise CommandError("%r is not a valid port number." % port)

        use_reloader = options.get('use_reloader', True)
        admin_media_path = options.get('admin_media_path', '')
        shutdown_message = options.get('shutdown_message', '')
        quit_command = (sys.platform
                        == 'win32') and 'CTRL-BREAK' or 'CONTROL-C'

        def inner_run():
            from google.appengine._internal.django.conf import settings
            from google.appengine._internal.django.utils import translation
            print("Validating models...")
            self.validate(display_num_errors=True)
            print("\nDjango version %s, using settings %r" %
                  (django.get_version(), settings.SETTINGS_MODULE))
            print("Development server is running at http://%s:%s/" %
                  (addr, port))
            print("Quit the server with %s." % quit_command)

            # django.core.management.base forces the locale to en-us. We should
            # set it up correctly for the first request (particularly important
            # in the "--noreload" case).
            translation.activate(settings.LANGUAGE_CODE)

            try:
                handler = AdminMediaHandler(WSGIHandler(), admin_media_path)
                run(addr, int(port), handler)
            except WSGIServerException as e:
                # Use helpful error messages instead of ugly tracebacks.
                ERRORS = {
                    13: "You don't have permission to access that port.",
                    98: "That port is already in use.",
                    99: "That IP address can't be assigned-to.",
                }
                try:
                    error_text = ERRORS[e.args[0].args[0]]
                except (AttributeError, KeyError):
                    error_text = str(e)
                sys.stderr.write(
                    self.style.ERROR("Error: %s" % error_text) + '\n')
                # Need to use an OS exit because sys.exit doesn't work in a thread
                os._exit(1)
            except KeyboardInterrupt:
                if shutdown_message:
                    print(shutdown_message)
                sys.exit(0)

        if use_reloader:
            from google.appengine._internal.django.utils import autoreload
            autoreload.main(inner_run)
        else:
            inner_run()
 def handle(self, *apps, **options):
     raise CommandError(
         "This command has been renamed. Use the 'sqlcustom' command instead."
     )