Commit e4e12875 authored by Honza Král's avatar Honza Král
Browse files

Merge pull request #817 from rybaktomasz/ticket_5568

Fixes #5568 -- DROP INDEX subcommand 
parents cbb9f629 5099f31a
Loading
Loading
Loading
Loading
+23 −0
Original line number Diff line number Diff line
from __future__ import unicode_literals

from optparse import make_option

from django.core.management.base import AppCommand
from django.core.management.sql import sql_destroy_indexes
from django.db import connections, DEFAULT_DB_ALIAS

class Command(AppCommand):
    help = "Prints the DROP INDEX SQL statements for the given model module name(s)."

    option_list = AppCommand.option_list + (
        make_option('--database', action='store', dest='database',
            default=DEFAULT_DB_ALIAS, help='Nominates a database to print the '
                'SQL for.  Defaults to the "default" database.'),

    )

    output_transaction = True

    def handle_app(self, app, **options):
        return '\n'.join(sql_destroy_indexes(app, self.style, connections[options.get('database')]))
+7 −0
Original line number Diff line number Diff line
@@ -137,6 +137,13 @@ def sql_indexes(app, style, connection):
        output.extend(connection.creation.sql_indexes_for_model(model, style))
    return output

def sql_destroy_indexes(app, style, connection):
    "Returns a list of the DROP INDEX SQL statements for all models in the given app."
    output = []
    for model in models.get_models(app):
        output.extend(connection.creation.sql_destroy_indexes_for_model(model, style))
    return output


def sql_all(app, style, connection):
    "Returns a list of CREATE TABLE SQL, initial-data inserts, and CREATE INDEX SQL for the given module."
+46 −0
Original line number Diff line number Diff line
@@ -259,6 +259,52 @@ class BaseDatabaseCreation(object):
        del references_to_delete[model]
        return output

    def sql_destroy_indexes_for_model(self, model, style):
        """
        Returns the DROP INDEX SQL statements for a single model.
        """
        if not model._meta.managed or model._meta.proxy or model._meta.swapped:
            return []
        output = []
        for f in model._meta.local_fields:
            output.extend(self.sql_destroy_indexes_for_field(model, f, style))
        for fs in model._meta.index_together:
            fields = [model._meta.get_field_by_name(f)[0] for f in fs]
            output.extend(self.sql_destroy_indexes_for_fields(model, fields, style))
        return output

    def sql_destroy_indexes_for_field(self, model, f, style):
        """
        Return the DROP INDEX SQL statements for a single model field.
        """
        if f.db_index and not f.unique:
            return self.sql_destroy_indexes_for_fields(model, [f], style)
        else:
            return []

    def sql_destroy_indexes_for_fields(self, model, fields, style):
        if len(fields) == 1 and fields[0].db_tablespace:
            tablespace_sql = self.connection.ops.tablespace_sql(fields[0].db_tablespace)
        elif model._meta.db_tablespace:
            tablespace_sql = self.connection.ops.tablespace_sql(model._meta.db_tablespace)
        else:
            tablespace_sql = ""
        if tablespace_sql:
            tablespace_sql = " " + tablespace_sql

        field_names = []
        qn = self.connection.ops.quote_name
        for f in fields:
            field_names.append(style.SQL_FIELD(qn(f.column)))

        index_name = "%s_%s" % (model._meta.db_table, self._digest([f.name for f in fields]))

        return [
            style.SQL_KEYWORD("DROP INDEX") + " " +
            style.SQL_TABLE(qn(truncate_name(index_name, self.connection.ops.max_name_length()))) + " " +
            ";",
        ]

    def create_test_db(self, verbosity=1, autoclobber=False):
        """
        Creates a test database, prompting the user for confirmation if the
+26 −0
Original line number Diff line number Diff line
@@ -41,3 +41,29 @@ class DatabaseCreation(BaseDatabaseCreation):
    def sql_for_inline_foreign_key_references(self, model, field, known_models, style):
        "All inline references are pending under MySQL"
        return [], True

    def sql_destroy_indexes_for_fields(self, model, fields, style):
        if len(fields) == 1 and fields[0].db_tablespace:
            tablespace_sql = self.connection.ops.tablespace_sql(fields[0].db_tablespace)
        elif model._meta.db_tablespace:
            tablespace_sql = self.connection.ops.tablespace_sql(model._meta.db_tablespace)
        else:
            tablespace_sql = ""
        if tablespace_sql:
            tablespace_sql = " " + tablespace_sql

        field_names = []
        qn = self.connection.ops.quote_name
        for f in fields:
            field_names.append(style.SQL_FIELD(qn(f.column)))

        index_name = "%s_%s" % (model._meta.db_table, self._digest([f.name for f in fields]))

        from ..util import truncate_name

        return [
            style.SQL_KEYWORD("DROP INDEX") + " " +
            style.SQL_TABLE(qn(truncate_name(index_name, self.connection.ops.max_name_length()))) + " " +
            style.SQL_KEYWORD("ON") + " " +
            style.SQL_TABLE(qn(model._meta.db_table)) + ";",
        ]
+10 −0
Original line number Diff line number Diff line
@@ -863,6 +863,16 @@ Note that the order in which the SQL files are processed is undefined.
The :djadminopt:`--database` option can be used to specify the database for
which to print the SQL.

sqldropindexes <appname appname ...>
--------------------------------

.. django-admin:: sqldropindexes

Prints the DROP INDEX SQL statements for the given app name(s).

The :djadminopt:`--database` option can be used to specify the database for
which to print the SQL.

sqlflush
--------

Loading