Пример #1
0
    def sequence_list(self):
        """
        Return a list of information about all DB sequences for all models in
        all apps.
        """
        from django.apps import apps
        from django.db import router

        sequence_list = []
        cursor = self.connection.cursor()

        for app_config in apps.get_app_configs():
            for model in router.get_migratable_models(app_config, self.connection.alias):
                if not model._meta.managed:
                    continue
                if model._meta.swapped:
                    continue
                sequence_list.extend(self.get_sequences(cursor, model._meta.db_table, model._meta.local_fields))
                for f in model._meta.local_many_to_many:
                    # If this is an m2m using an intermediate table,
                    # we don't need to reset the sequence.
                    if f.remote_field.through is None:
                        sequence = self.get_sequences(cursor, f.m2m_db_table())
                        sequence_list.extend(sequence or [{'table': f.m2m_db_table(), 'column': None}])
        return sequence_list
Пример #2
0
    def sync_apps(self, connection, app_labels):
        "Runs the old syncdb-style operation on a list of app_labels."
        cursor = connection.cursor()

        try:
            # Get a list of already installed *models* so that references work right.
            tables = connection.introspection.table_names(cursor)
            created_models = set()

            # Build the manifest of apps and models that are to be synchronized
            all_models = [
                (app_config.label,
                    router.get_migratable_models(app_config, connection.alias, include_auto_created=False))
                for app_config in apps.get_app_configs()
                if app_config.models_module is not None and app_config.label in app_labels
            ]

            def model_installed(model):
                opts = model._meta
                converter = connection.introspection.table_name_converter
                # Note that if a model is unmanaged we short-circuit and never try to install it
                return not (
                    (converter(opts.db_table) in tables) or
                    (opts.auto_created and converter(opts.auto_created._meta.db_table) in tables)
                )

            manifest = OrderedDict(
                (app_name, list(filter(model_installed, model_list)))
                for app_name, model_list in all_models
            )

            # Create the tables for each model
            if self.verbosity >= 1:
                self.stdout.write("  Creating tables...\n")
            with transaction.atomic(using=connection.alias, savepoint=connection.features.can_rollback_ddl):
                deferred_sql = []
                for app_name, model_list in manifest.items():
                    for model in model_list:
                        if not model._meta.can_migrate(connection):
                            continue
                        if self.verbosity >= 3:
                            self.stdout.write(
                                "    Processing %s.%s model\n" % (app_name, model._meta.object_name)
                            )
                        with connection.schema_editor() as editor:
                            if self.verbosity >= 1:
                                self.stdout.write("    Creating table %s\n" % model._meta.db_table)
                            editor.create_model(model)
                            deferred_sql.extend(editor.deferred_sql)
                            editor.deferred_sql = []
                        created_models.add(model)

                if self.verbosity >= 1:
                    self.stdout.write("    Running deferred SQL...\n")
                for statement in deferred_sql:
                    cursor.execute(statement)
        finally:
            cursor.close()

        return created_models
Пример #3
0
    def sequence_list(self):
        "Returns a list of information about all DB sequences for all models in all apps."
        from django.apps import apps
        from django.db import models, router

        sequence_list = []

        for app_config in apps.get_app_configs():
            for model in router.get_migratable_models(app_config, self.connection.alias):
                if not model._meta.managed:
                    continue
                if model._meta.swapped:
                    continue
                for f in model._meta.local_fields:
                    if isinstance(f, models.AutoField):
                        sequence_list.append({'table': model._meta.db_table, 'column': f.column})
                        break  # Only one AutoField is allowed per model, so don't bother continuing.

                for f in model._meta.local_many_to_many:
                    # If this is an m2m using an intermediate table,
                    # we don't need to reset the sequence.
                    if f.remote_field.through is None:
                        sequence_list.append({'table': f.m2m_db_table(), 'column': None})

        return sequence_list
Пример #4
0
    def sequence_list(self):
        """
        Return a list of information about all DB sequences for all models in
        all apps.
        """
        from django.apps import apps
        from django.db import router

        sequence_list = []
        with self.connection.cursor() as cursor:
            for app_config in apps.get_app_configs():
                for model in router.get_migratable_models(
                        app_config, self.connection.alias):
                    if not model._meta.managed:
                        continue
                    if model._meta.swapped:
                        continue
                    sequence_list.extend(
                        self.get_sequences(cursor, model._meta.db_table,
                                           model._meta.local_fields))
                    for f in model._meta.local_many_to_many:
                        # If this is an m2m using an intermediate table,
                        # we don't need to reset the sequence.
                        if f.remote_field.through._meta.auto_created:
                            sequence = self.get_sequences(
                                cursor, f.m2m_db_table())
                            sequence_list.extend(sequence
                                                 or [{
                                                     'table': f.m2m_db_table(),
                                                     'column': None
                                                 }])
        return sequence_list
Пример #5
0
    def django_table_names(self, only_existing=False, include_views=True):
        """
        Returns a list of all table names that have associated Django models and
        are in INSTALLED_APPS.

        If only_existing is True, the resulting list will only include the tables
        that actually exist in the database.
        """
        from django.apps import apps
        from django.db import router
        tables = set()
        for app_config in apps.get_app_configs():
            for model in router.get_migratable_models(app_config, self.connection.alias):
                if not model._meta.managed:
                    continue
                tables.add(model._meta.db_table)
                tables.update(f.m2m_db_table() for f in model._meta.local_many_to_many)
        tables = list(tables)
        if only_existing:
            existing_tables = self.table_names(include_views=include_views)
            tables = [
                t
                for t in tables
                if self.table_name_converter(t) in existing_tables
            ]
        return tables
Пример #6
0
    def sync_apps(self, connection, app_labels):
        """Run the old syncdb-style operation on a list of app_labels."""
        with connection.cursor() as cursor:
            tables = connection.introspection.table_names(cursor)

        # Build the manifest of apps and models that are to be synchronized.
        all_models = [
            (
                app_config.label,
                router.get_migratable_models(app_config, connection.alias, include_auto_created=False),
            )
            for app_config in apps.get_app_configs()
            if app_config.models_module is not None and app_config.label in app_labels
        ]

        def model_installed(model):
            opts = model._meta
            converter = connection.introspection.identifier_converter
            return not (
                (converter(opts.db_table) in tables) or
                (opts.auto_created and converter(opts.auto_created._meta.db_table) in tables)
            )

        manifest = {
            app_name: list(filter(model_installed, model_list))
            for app_name, model_list in all_models
        }

        # Create the tables for each model
        if self.verbosity >= 1:
            self.stdouimport time
Пример #7
0
 def get_migratable_models(self):
     from django.apps import apps
     from django.db import router
     return (model for app_config in apps.get_app_configs()
             for model in router.get_migratable_models(
                 app_config, self.connection.alias)
             if model._meta.can_migrate(self.connection))
Пример #8
0
    def sync_apps(self, connection, app_labels):
        "Runs the old syncdb-style operation on a list of app_labels."
        cursor = connection.cursor()

        try:
            # Get a list of already installed *models* so that references work right.
            tables = connection.introspection.table_names(cursor)
            created_models = set()

            # Build the manifest of apps and models that are to be synchronized
            all_models = [
                (app_config.label,
                    router.get_migratable_models(app_config, connection.alias, include_auto_created=False))
                for app_config in apps.get_app_configs()
                if app_config.models_module is not None and app_config.label in app_labels
            ]

            def model_installed(model):
                opts = model._meta
                converter = connection.introspection.table_name_converter
                # Note that if a model is unmanaged we short-circuit and never try to install it
                return not (
                    (converter(opts.db_table) in tables) or
                    (opts.auto_created and converter(opts.auto_created._meta.db_table) in tables)
                )

            manifest = OrderedDict(
                (app_name, list(filter(model_installed, model_list)))
                for app_name, model_list in all_models
            )

            # Create the tables for each model
            if self.verbosity >= 1:
                self.stdout.write("  Creating tables...\n")
            with transaction.atomic(using=connection.alias, savepoint=connection.features.can_rollback_ddl):
                deferred_sql = []
                for app_name, model_list in manifest.items():
                    for model in model_list:
                        if not model._meta.can_migrate(connection):
                            continue
                        if self.verbosity >= 3:
                            self.stdout.write(
                                "    Processing %s.%s model\n" % (app_name, model._meta.object_name)
                            )
                        with connection.schema_editor() as editor:
                            if self.verbosity >= 1:
                                self.stdout.write("    Creating table %s\n" % model._meta.db_table)
                            editor.create_model(model)
                            deferred_sql.extend(editor.deferred_sql)
                            editor.deferred_sql = []
                        created_models.add(model)

                if self.verbosity >= 1:
                    self.stdout.write("    Running deferred SQL...\n")
                for statement in deferred_sql:
                    cursor.execute(statement)
        finally:
            cursor.close()

        return created_models
Пример #9
0
def sql_create(app_config, 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 database.
        raise CommandError(
            "Django doesn't know which syntax to use for your SQL statements,"
            "\nbecause you haven't properly specified the ENGINE setting for "
            "the database.\n"
            "see: https://docs.djangoproject.com/en/%s/ref/settings/"
            "#databases" % get_docs_version())

    # 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).
    final_output = []
    output = []

    for model in router.get_migratable_models(app_config,
                                              connection.alias,
                                              include_auto_created=True):
        with connection.schema_editor() as editor:
            output += sql_create_model(editor, model)
            final_output.extend(editor.deferred_sql)
            editor.deferred_sql = []
    if get_docs_version().startswith('2'):
        # Content of final_output are Statement objects which need to be
        # converted as str
        final_output = [str(statement) for statement in final_output]
    return output + final_output
Пример #10
0
 def emit_post_migrate(verbosity, interactive, database):
     # Emit the post migrate signal. This allows individual applications to
     # respond as if the database had been migrated from scratch.
     all_models = []
     for app_config in apps.get_app_configs():
         all_models.extend(router.get_migratable_models(app_config, database, include_auto_created=True))
     emit_post_migrate_signal(set(all_models), verbosity, interactive, database)
Пример #11
0
 def emit_post_migrate(verbosity, interactive, database):
     # Emit the post migrate signal. This allows individual applications to
     # respond as if the database had been migrated from scratch.
     all_models = []
     for app_config in apps.get_app_configs():
         all_models.extend(router.get_migratable_models(app_config, database, include_auto_created=True))
     emit_post_migrate_signal(set(all_models), verbosity, interactive, database)
Пример #12
0
    def sequence_list(self):
        """
        Return a list of information about all DB sequences for all models in
        all apps.
        """
        from django.apps import apps
        from django.db import models, router

        sequence_list = []

        for app_config in apps.get_app_configs():
            for model in router.get_migratable_models(app_config,
                                                      self.connection.alias):
                if not model._meta.managed:
                    continue
                if model._meta.swapped:
                    continue
                for f in model._meta.local_fields:
                    if isinstance(f, models.AutoField):
                        sequence_list.append({
                            'table': model._meta.db_table,
                            'column': f.column
                        })
                        break  # Only one AutoField is allowed per model, so don't bother continuing.

                for f in model._meta.local_many_to_many:
                    # If this is an m2m using an intermediate table,
                    # we don't need to reset the sequence.
                    if f.remote_field.through is None:
                        sequence_list.append({
                            'table': f.m2m_db_table(),
                            'column': None
                        })

        return sequence_list
Пример #13
0
    def handle(self, *args, **options):
        db_values = []
        db = options.get('database')
        connection = connections[db]
        connection.prepare_database()

        # Build the manifest of apps and models that are to be synchronized
        all_models = [
            (app_config.label,
             router.get_migratable_models(app_config, connection.alias, include_auto_created=False))
            for app_config in apps.get_app_configs()
            ]

        for app_name, model_list in all_models:
            for m in model_list:
                if hasattr(m, '_translation_fields'):
                    for x in m._translation_fields:
                        for y in m.objects.all():
                            db_values.append(getattr(y, x))

                    path = apps.app_configs[app_name].path
                    # print db_values
                    with open(os.path.join(path, 'extra_translations.py'), 'w') as f:
                        translations_file = File(f)
                        translations_file.write('''# encoding: utf-8

from __future__ import unicode_literals, absolute_import
from django.utils.translation import ugettext_lazy as _

translations = (
''')
                        for v in db_values:
                            translations_file.write("""    _('%s'),\n""" % smart_str(v.replace('\'', '\\\'')))
                        translations_file.write(')')
Пример #14
0
    def django_table_names(self, only_existing=False, include_views=True):
        """
        Return a list of all table names that have associated Django models and
        are in INSTALLED_APPS.

        If only_existing is True, include only the tables in the database.
        """
        from django.apps import apps
        from django.db import router
        tables = set()
        for app_config in apps.get_app_configs():
            for model in router.get_migratable_models(app_config,
                                                      self.connection.alias):
                if not model._meta.managed:
                    continue
                tables.add(model._meta.db_table)
                tables.update(f.m2m_db_table()
                              for f in model._meta.local_many_to_many
                              if f.remote_field.through._meta.managed)
        tables = list(tables)
        if only_existing:
            existing_tables = self.table_names(include_views=include_views)
            tables = [
                t for t in tables
                if self.table_name_converter(t) in existing_tables
            ]
        return tables
Пример #15
0
def sql_indexes(app_config, style, connection):
    "Returns a list of the CREATE INDEX SQL statements for all models in the given app."
    output = []
    for model in router.get_migratable_models(app_config,
                                              connection.alias,
                                              include_auto_created=True):
        output.extend(connection.creation.sql_indexes_for_model(model, style))
    return output
Пример #16
0
def sql_destroy_indexes(app_config, style, connection):
    "Returns a list of the DROP INDEX SQL statements for all models in the given app."

    check_for_migrations(app_config, connection)

    output = []
    for model in router.get_migratable_models(app_config, connection.alias, include_auto_created=True):
        output.extend(connection.creation.sql_destroy_indexes_for_model(model, style))
    return output
Пример #17
0
    def sync_apps(self, connection, app_labels):
        """Run the old syncdb-style operation on a list of app_labels."""
        with connection.cursor() as cursor:
            tables = connection.introspection.table_names(cursor)

        # Build the manifest of apps and models that are to be synchronized.
        all_models = [
            (
                app_config.label,
                router.get_migratable_models(
                    app_config, connection.alias, include_auto_created=False
                ),
            )
            for app_config in apps.get_app_configs()
            if app_config.models_module is not None and app_config.label in app_labels
        ]

        def model_installed(model):
            opts = model._meta
            converter = connection.introspection.identifier_converter
            return not (
                (converter(opts.db_table) in tables)
                or (
                    opts.auto_created
                    and converter(opts.auto_created._meta.db_table) in tables
                )
            )

        manifest = OrderedDict(
            (app_name, list(filter(model_installed, model_list)))
            for app_name, model_list in all_models
        )

        # Create the tables for each model
        if self.verbosity >= 1:
            self.stdout.write("  Creating tables...\n")
        with connection.schema_editor() as editor:
            for app_name, model_list in manifest.items():
                for model in model_list:
                    # Never install unmanaged models, etc.
                    if not model._meta.can_migrate(connection):
                        continue
                    if self.verbosity >= 3:
                        self.stdout.write(
                            "    Processing %s.%s model\n"
                            % (app_name, model._meta.object_name)
                        )
                    if self.verbosity >= 1:
                        self.stdout.write(
                            "    Creating table %s\n" % model._meta.db_table
                        )
                    editor.create_model(model)

            # Deferred SQL is executed when exiting the editor's context.
            if self.verbosity >= 1:
                self.stdout.write("    Running deferred SQL...\n")
Пример #18
0
def sql_delete(app_config, style, connection, close_connection=True):
    "Returns a list of the DROP TABLE SQL statements for the given app."

    check_for_migrations(app_config, connection)

    # This should work even if a connection isn't available
    try:
        cursor = connection.cursor()
    except Exception:
        cursor = None

    try:
        # Figure out which tables already exist
        if cursor:
            table_names = connection.introspection.table_names(cursor)
        else:
            table_names = []

        output = []

        # Output DROP TABLE statements for standard application tables.
        to_delete = set()

        references_to_delete = {}
        app_models = router.get_migratable_models(app_config,
                                                  connection.alias,
                                                  include_auto_created=True)
        for model in app_models:
            if cursor and connection.introspection.table_name_converter(
                    model._meta.db_table) in table_names:
                # The table exists, so it needs to be dropped
                opts = model._meta
                for f in opts.local_fields:
                    if f.rel and f.rel.to not in to_delete:
                        references_to_delete.setdefault(f.rel.to, []).append(
                            (model, f))

                to_delete.add(model)

        for model in app_models:
            if connection.introspection.table_name_converter(
                    model._meta.db_table) in table_names:
                output.extend(
                    connection.creation.sql_destroy_model(
                        model, references_to_delete, style))
    finally:
        # Close database connection explicitly, in case this output is being piped
        # directly into a database client, to avoid locking issues.
        if cursor and close_connection:
            cursor.close()
            connection.close()

    if not output:
        output.append(
            '-- App creates no tables in the database. Nothing to do.')
    return output[::-1]  # Reverse it, to deal with table dependencies.
Пример #19
0
def sql_custom(app, style, connection):
    "Returns a list of the custom table modifying SQL statements for the given app."
    output = []

    app_models = router.get_migratable_models(app, connection.alias)

    for model in app_models:
        output.extend(custom_sql_for_model(model, style, connection))

    return output
Пример #20
0
    def installed_models(self, tables):
        "Returns a set of all models represented by the provided list of table names."
        from django.apps import apps
        from django.db import router

        all_models = []
        for app_config in apps.get_app_configs():
            all_models.extend(router.get_migratable_models(app_config, self.connection.alias))
        tables = list(map(self.table_name_converter, tables))
        return {m for m in all_models if self.table_name_converter(m._meta.db_table) in tables}
Пример #21
0
def sql_custom(app_config, style, connection):
    "Returns a list of the custom table modifying SQL statements for the given app."
    output = []

    app_models = router.get_migratable_models(app_config, connection.alias)

    for model in app_models:
        output.extend(custom_sql_for_model(model, style, connection))

    return output
Пример #22
0
 def installed_models(self, tables):
     "Returns a set of all models represented by the provided list of table names."
     from django.apps import apps
     from django.db import router
     all_models = []
     for app_config in apps.get_app_configs():
         all_models.extend(router.get_migratable_models(app_config, self.connection.alias))
     tables = list(map(self.table_name_converter, tables))
     return {
         m for m in all_models
         if self.table_name_converter(m._meta.db_table) in tables
     }
Пример #23
0
def sql_create(app_config, style, connection):
    "Returns a list of the CREATE TABLE SQL statements for the given app."

    check_for_migrations(app_config, connection)

    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 database.
        raise CommandError(
            "Django doesn't know which syntax to use for your SQL statements,\n"
            + "because you haven't properly specified the ENGINE setting for the database.\n"
            + "see: https://docs.djangoproject.com/en/dev/ref/settings/#databases"
        )

    # 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 = app_config.get_models(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 router.get_migratable_models(app_config, connection.alias, include_auto_created=True):
        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
Пример #24
0
def sql_delete(app_config, style, connection, close_connection=True):
    "Returns a list of the DROP TABLE SQL statements for the given app."

    check_for_migrations(app_config, connection)

    # This should work even if a connection isn't available
    try:
        cursor = connection.cursor()
    except Exception:
        cursor = None

    try:
        # Figure out which tables already exist
        if cursor:
            table_names = connection.introspection.table_names(cursor)
        else:
            table_names = []

        output = []

        # Output DROP TABLE statements for standard application tables.
        to_delete = set()

        references_to_delete = {}
        app_models = router.get_migratable_models(app_config, connection.alias, include_auto_created=True)
        for model in app_models:
            if cursor and connection.introspection.table_name_converter(model._meta.db_table) in table_names:
                # The table exists, so it needs to be dropped
                opts = model._meta
                for f in opts.local_fields:
                    if f.rel and f.rel.to not in to_delete:
                        references_to_delete.setdefault(f.rel.to, []).append((model, f))

                to_delete.add(model)

        for model in app_models:
            if connection.introspection.table_name_converter(model._meta.db_table) in table_names:
                output.extend(connection.creation.sql_destroy_model(model, references_to_delete, style))
    finally:
        # Close database connection explicitly, in case this output is being piped
        # directly into a database client, to avoid locking issues.
        if cursor and close_connection:
            cursor.close()
            connection.close()

    if not output:
        output.append('-- App creates no tables in the database. Nothing to do.')
    return output[::-1]  # Reverse it, to deal with table dependencies.
Пример #25
0
    def sync_apps(self, connection, app_labels):
        """Run the old syncdb-style operation on a list of app_labels."""
        with connection.cursor() as cursor:
            tables = connection.introspection.table_names(cursor)

        # Build the manifest of apps and models that are to be synchronized.
        all_models = [
            (
                app_config.label,
                router.get_migratable_models(app_config, connection.alias, include_auto_created=False),
            )
            for app_config in apps.get_app_configs()
            if app_config.models_module is not None and app_config.label in app_labels
        ]

        def model_installed(model):
            opts = model._meta
            converter = connection.introspection.table_name_converter
            return not (
                (converter(opts.db_table) in tables) or
                (opts.auto_created and converter(opts.auto_created._meta.db_table) in tables)
            )

        manifest = OrderedDict(
            (app_name, list(filter(model_installed, model_list)))
            for app_name, model_list in all_models
        )

        # Create the tables for each model
        if self.verbosity >= 1:
            self.stdout.write("  Creating tables…\n")
        with connection.schema_editor() as editor:
            for app_name, model_list in manifest.items():
                for model in model_list:
                    # Never install unmanaged models, etc.
                    if not model._meta.can_migrate(connection):
                        continue
                    if self.verbosity >= 3:
                        self.stdout.write(
                            "    Processing %s.%s model\n" % (app_name, model._meta.object_name)
                        )
                    if self.verbosity >= 1:
                        self.stdout.write("    Creating table %s\n" % model._meta.db_table)
                    editor.create_model(model)

            # Deferred SQL is executed when exiting the editor's context.
            if self.verbosity >= 1:
                self.stdout.write("    Running deferred SQL…\n")
Пример #26
0
def sql_create(app_config, style, connection):
    "Returns a list of the CREATE TABLE SQL statements for the given app."

    check_for_migrations(app_config, connection)

    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 database.
        raise CommandError("Django doesn't know which syntax to use for your SQL statements,\n" +
            "because you haven't properly specified the ENGINE setting for the database.\n" +
            "see: https://docs.djangoproject.com/en/dev/ref/settings/#databases")

    # 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 = list(app_config.get_models(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 router.get_migratable_models(app_config, connection.alias, include_auto_created=True):
        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
Пример #27
0
    def sequencelist(self):
        """Returns a list of information about all DB sequences for all models in all apps."""

        sequence_list = []
        try:
            assert os.environ.get(
                "DJANGO_SETTINGS_MODULE"
            ), "No DJANGO_SETTINGS_MODULE variable defined"
        except AssertionError as aerr:
            raise aerr

        for app_config in apps.get_app_configs():
            for model in router.get_migratable_models(app_config,
                                                      self.connection.alias):
                if not model._meta.managed:
                    continue
                if model._meta.swapped:
                    continue
                for f in model._meta.local_fields:
                    if isinstance(f, models.AutoField):
                        sequence_list.append({
                            'table': model._meta.db_table,
                            'column': f.column
                        })
                        break  # Only one AutoField is allowed per model, so don't bother continuing.

                for f in model._meta.local_many_to_many:
                    # If this is an m2m using an intermediate table,
                    # we don't need to reset the sequence.
                    if f.rel.through is None:
                        sequence_list.append({
                            'table': f.m2m_db_table(),
                            'column': None
                        })

        return sequence_list
Пример #28
0
    def sync_apps(self, connection, app_labels):
        "Runs the old syncdb-style operation on a list of app_labels."
        cursor = connection.cursor()

        try:
            # Get a list of already installed *models* so that references work right.
            tables = connection.introspection.table_names(cursor)
            created_models = set()

            # Build the manifest of apps and models that are to be synchronized
            all_models = [
                (app_config.label,
                    router.get_migratable_models(app_config, connection.alias, include_auto_created=False))
                for app_config in apps.get_app_configs()
                if app_config.models_module is not None and app_config.label in app_labels
            ]

            def model_installed(model):
                opts = model._meta
                converter = connection.introspection.table_name_converter
                # Note that if a model is unmanaged we short-circuit and never try to install it
                return not ((converter(opts.db_table) in tables) or
                    (opts.auto_created and converter(opts.auto_created._meta.db_table) in tables))

            manifest = OrderedDict(
                (app_name, list(filter(model_installed, model_list)))
                for app_name, model_list in all_models
            )

            # Create the tables for each model
            if self.verbosity >= 1:
                self.stdout.write("  Creating tables...\n")
            with transaction.atomic(using=connection.alias, savepoint=connection.features.can_rollback_ddl):
                deferred_sql = []
                for app_name, model_list in manifest.items():
                    for model in model_list:
                        if model._meta.proxy or not model._meta.managed:
                            continue
                        if self.verbosity >= 3:
                            self.stdout.write(
                                "    Processing %s.%s model\n" % (app_name, model._meta.object_name)
                            )
                        with connection.schema_editor() as editor:
                            if self.verbosity >= 1:
                                self.stdout.write("    Creating table %s\n" % model._meta.db_table)
                            editor.create_model(model)
                            deferred_sql.extend(editor.deferred_sql)
                            editor.deferred_sql = []
                        created_models.add(model)

                if self.verbosity >= 1:
                    self.stdout.write("    Running deferred SQL...\n")
                for statement in deferred_sql:
                    cursor.execute(statement)
        finally:
            cursor.close()

        # The connection may have been closed by a syncdb handler.
        cursor = connection.cursor()
        try:
            # Install custom SQL for the app (but only if this
            # is a model we've just created)
            if self.verbosity >= 1:
                self.stdout.write("  Installing custom SQL...\n")
            for app_name, model_list in manifest.items():
                for model in model_list:
                    if model in created_models:
                        custom_sql = custom_sql_for_model(model, no_style(), connection)
                        if custom_sql:
                            if self.verbosity >= 2:
                                self.stdout.write(
                                    "    Installing custom SQL for %s.%s model\n" %
                                    (app_name, model._meta.object_name)
                                )
                            try:
                                with transaction.atomic(using=connection.alias):
                                    for sql in custom_sql:
                                        cursor.execute(sql)
                            except Exception as e:
                                self.stderr.write(
                                    "    Failed to install custom SQL for %s.%s model: %s\n"
                                    % (app_name, model._meta.object_name, e)
                                )
                                if self.show_traceback:
                                    traceback.print_exc()
                        else:
                            if self.verbosity >= 3:
                                self.stdout.write(
                                    "    No custom SQL for %s.%s model\n" %
                                    (app_name, model._meta.object_name)
                                )
        finally:
            cursor.close()

        # Load initial_data fixtures (unless that has been disabled)
        if self.load_initial_data:
            for app_label in app_labels:
                call_command(
                    'loaddata', 'initial_data', verbosity=self.verbosity,
                    database=connection.alias, app_label=app_label,
                    hide_empty=True,
                )

        return created_models
Пример #29
0
    def sync_apps(self, connection, app_labels):
        "Runs the old syncdb-style operation on a list of app_labels."
        cursor = connection.cursor()

        try:
            # Get a list of already installed *models* so that references work right.
            tables = connection.introspection.table_names(cursor)
            created_models = set()

            # Build the manifest of apps and models that are to be synchronized
            all_models = [
                (app_config.label,
                 router.get_migratable_models(app_config, connection.alias, include_auto_created=False))
                for app_config in apps.get_app_configs()
                if app_config.models_module is not None and app_config.label in app_labels
                ]

            def model_installed(model):
                opts = model._meta
                converter = connection.introspection.identifier_converter

                # Note that if a model isn't managed we short-circuit and never try to install it
                return not (
                    (converter(opts.db_table) in tables) or
                    (opts.auto_created and converter(opts.auto_created._meta.db_table) in tables)
                )
            manifest = OrderedDict(
                (app_name, list(filter(model_installed, model_list)))
                for app_name, model_list in all_models
            )

            # Create the tables for each model
            if self.verbosity >= 1:
                self.stdout.write("  Creating tables...\n")

            with transaction.atomic(using=connection.alias, savepoint=connection.features.can_rollback_ddl):

                with connection.schema_editor() as editor:
                    editor.execute("CREATE SCHEMA {}".format(settings.POSTGRES_TEMPLATE_SCHEMA))
                    statements = editor.connection.ops.prepare_sql_script(CLONE_SCHEMA)
                    for statement in statements:
                        editor.execute(statement, params=None)

                schema_deferred_sql = {}

                with connection.schema_editor() as editor:
                    schema_model = apps.get_model(settings.POSTGRES_SCHEMA_MODEL)
                    editor.create_model(schema_model, verbosity=self.verbosity)
                    schema_deferred_sql.update(editor.schema_deferred_sql)
                    editor.schema_deferred_sql = {}
                    created_models.add(schema_model)

                for app_name, model_list in manifest.items():
                    for model in model_list:
                        if not model._meta.can_migrate(connection):
                            continue
                        if model in created_models:
                            continue  # probably schema model
                        if self.verbosity >= 3:
                            self.stdout.write(
                                "    Processing %s.%s model\n" % (app_name, model._meta.object_name)
                            )
                        with connection.schema_editor() as editor:
                            editor.schema_deferred_sql.update(schema_deferred_sql)
                            editor.create_model(model, verbosity=self.verbosity)
                            schema_deferred_sql.update(editor.schema_deferred_sql)
                            editor.schema_deferred_sql = {}
                            created_models.add(model)

                if self.verbosity >= 1:
                    self.stdout.write("\n    Running deferred SQL...\n")
                with connection.schema_editor() as editor:
                    editor.schema_deferred_sql = schema_deferred_sql

        finally:
            cursor.close()

        return created_models
Пример #30
0
# -*- coding: utf-8 -*-
Пример #31
0
def sql_indexes(app, style, connection):
    "Returns a list of the CREATE INDEX SQL statements for all models in the given app."
    output = []
    for model in router.get_migratable_models(app, connection.alias, include_auto_created=True):
        output.extend(connection.creation.sql_indexes_for_model(model, style))
    return output
Пример #32
0
def ordered_models_to_delete(app_config, connection):
    """Models of the given app to delete.
    @return A tuple (models, loop_error).
            'models' is a list of the models classes to delete ;
                     the order respects the dependencies between the models.
            'loop_error' is a boolean which indicates dependencies loop error.
    """
    from django.db import router
    from django.utils.datastructures import OrderedSet

    from creme.creme_core.utils.dependence_sort import dependence_sort, DependenciesLoopError

    class ModelInfo:
        # def __init__(self, model, dependencies, sql_cmd):
        def __init__(self, model, dependencies):
            self.model = model
            self.dependencies = dependencies
            # self.sql_cmd = sql_cmd

        def __str__(self):
            return 'ModelInfo(model={model}, dependencies={dependencies})'.format(
                model=self.model.__name__,
                dependencies=[d.__name__ for d in self.dependencies],
            )

    models_info = []
    cursor = connection.cursor()

    try:
        table_names = set(connection.introspection.table_names(cursor))
        app_models = OrderedSet(
            router.get_migratable_models(
                app_config,
                connection.alias,
                # include_auto_created=True,
                # NB: the auto created tables are automatically
                #     deleted by schema_editor.delete_model(model)
                include_auto_created=False,
            ))

        for model in app_models:
            meta = model._meta

            if connection.introspection.table_name_converter(
                    meta.db_table) in table_names:
                # dependencies = []
                dependencies = set()  # We use a set to avoid duplicates

                for f in meta.local_fields:
                    # if f.rel:
                    if f.remote_field:
                        # related_model = f.rel.to
                        related_model = f.remote_field.model

                        # if related_model in app_models:
                        # NB: we avoid self-referencing (TODO: improve dependence_sort() ?)
                        if related_model is not model and related_model in app_models:
                            # dependencies.append(related_model)
                            dependencies.add(related_model)

                models_info.append(
                    ModelInfo(
                        model=model,
                        dependencies=dependencies,
                        # sql_cmd=connection.creation.sql_destroy_model(model, [], style)[0],
                    ))
    finally:
        cursor.close()

    dep_error = False
    try:
        models_info = dependence_sort(
            models_info,
            get_key=lambda mi: mi.model,
            get_dependencies=lambda mi: mi.dependencies,
        )
    except DependenciesLoopError:
        dep_error = True
    else:
        models_info.reverse()  # The dependencies must be deleted _after_

    # return [mi.sql_cmd for mi in models_info], dep_error
    return [mi.model for mi in models_info], dep_error
Пример #33
0
    def sync_apps(self, connection, app_labels):
        "Runs the old syncdb-style operation on a list of app_labels."
        cursor = connection.cursor()

        try:
            # Get a list of already installed *models* so that references work right.
            tables = connection.introspection.table_names(cursor)
            created_models = set()

            # Build the manifest of apps and models that are to be synchronized
            all_models = [
                (app_config.label,
                 router.get_migratable_models(app_config,
                                              connection.alias,
                                              include_auto_created=False))
                for app_config in apps.get_app_configs()
                if app_config.models_module is not None
                and app_config.label in app_labels
            ]

            def model_installed(model):
                opts = model._meta
                converter = connection.introspection.table_name_converter
                # Note that if a model is unmanaged we short-circuit and never try to install it
                return not ((converter(opts.db_table) in tables) or
                            (opts.auto_created and converter(
                                opts.auto_created._meta.db_table) in tables))

            manifest = OrderedDict(
                (app_name, list(filter(model_installed, model_list)))
                for app_name, model_list in all_models)

            create_models = set(itertools.chain(*manifest.values()))
            emit_pre_migrate_signal(create_models, self.verbosity,
                                    self.interactive, connection.alias)

            # Create the tables for each model
            if self.verbosity >= 1:
                self.stdout.write("  Creating tables...\n")
            with transaction.atomic(
                    using=connection.alias,
                    savepoint=connection.features.can_rollback_ddl):
                deferred_sql = []
                for app_name, model_list in manifest.items():
                    for model in model_list:
                        if model._meta.proxy or not model._meta.managed:
                            continue
                        if self.verbosity >= 3:
                            self.stdout.write(
                                "    Processing %s.%s model\n" %
                                (app_name, model._meta.object_name))
                        with connection.schema_editor() as editor:
                            if self.verbosity >= 1:
                                self.stdout.write("    Creating table %s\n" %
                                                  model._meta.db_table)
                            editor.create_model(model)
                            deferred_sql.extend(editor.deferred_sql)
                            editor.deferred_sql = []
                        created_models.add(model)

                if self.verbosity >= 1:
                    self.stdout.write("    Running deferred SQL...\n")
                for statement in deferred_sql:
                    cursor.execute(statement)
        finally:
            cursor.close()

        # The connection may have been closed by a syncdb handler.
        cursor = connection.cursor()
        try:
            # Install custom SQL for the app (but only if this
            # is a model we've just created)
            if self.verbosity >= 1:
                self.stdout.write("  Installing custom SQL...\n")
            for app_name, model_list in manifest.items():
                for model in model_list:
                    if model in created_models:
                        custom_sql = custom_sql_for_model(
                            model, no_style(), connection)
                        if custom_sql:
                            if self.verbosity >= 2:
                                self.stdout.write(
                                    "    Installing custom SQL for %s.%s model\n"
                                    % (app_name, model._meta.object_name))
                            try:
                                with transaction.atomic(
                                        using=connection.alias):
                                    for sql in custom_sql:
                                        cursor.execute(sql)
                            except Exception as e:
                                self.stderr.write(
                                    "    Failed to install custom SQL for %s.%s model: %s\n"
                                    % (app_name, model._meta.object_name, e))
                                if self.show_traceback:
                                    traceback.print_exc()
                        else:
                            if self.verbosity >= 3:
                                self.stdout.write(
                                    "    No custom SQL for %s.%s model\n" %
                                    (app_name, model._meta.object_name))
        finally:
            cursor.close()

        # Load initial_data fixtures (unless that has been disabled)
        if self.load_initial_data:
            for app_label in app_labels:
                call_command(
                    'loaddata',
                    'initial_data',
                    verbosity=self.verbosity,
                    database=connection.alias,
                    app_label=app_label,
                    hide_empty=True,
                )

        return created_models
Пример #34
0
    def sync_apps(self, connection, app_labels):
        "Runs the old syncdb-style operation on a list of app_labels."
        cursor = connection.cursor()

        try:
            # Get a list of already installed *models* so that references work right.
            tables = connection.introspection.table_names(cursor)
            seen_models = connection.introspection.installed_models(tables)
            created_models = set()
            pending_references = {}

            # Build the manifest of apps and models that are to be synchronized
            all_models = [
                (app_config.label,
                 router.get_migratable_models(app_config,
                                              connection.alias,
                                              include_auto_created=True))
                for app_config in apps.get_app_configs()
                if app_config.models_module is not None
                and app_config.label in app_labels
            ]

            def model_installed(model):
                opts = model._meta
                converter = connection.introspection.table_name_converter
                # Note that if a model is unmanaged we short-circuit and never try to install it
                return not ((converter(opts.db_table) in tables) or
                            (opts.auto_created and converter(
                                opts.auto_created._meta.db_table) in tables))

            manifest = OrderedDict(
                (app_name, list(filter(model_installed, model_list)))
                for app_name, model_list in all_models)

            create_models = set(itertools.chain(*manifest.values()))
            emit_pre_migrate_signal(create_models, self.verbosity,
                                    self.interactive, connection.alias)

            # Create the tables for each model
            if self.verbosity >= 1:
                self.stdout.write("  Creating tables...\n")
            with transaction.atomic(using=connection.alias, savepoint=False):
                for app_name, model_list in manifest.items():
                    for model in model_list:
                        # Create the model's database table, if it doesn't already exist.
                        if self.verbosity >= 3:
                            self.stdout.write(
                                "    Processing %s.%s model\n" %
                                (app_name, model._meta.object_name))
                        sql, references = connection.creation.sql_create_model(
                            model, no_style(), seen_models)
                        seen_models.add(model)
                        created_models.add(model)
                        for refto, refs in references.items():
                            pending_references.setdefault(refto,
                                                          []).extend(refs)
                            if refto in seen_models:
                                sql.extend(
                                    connection.creation.
                                    sql_for_pending_references(
                                        refto, no_style(), pending_references))
                        sql.extend(
                            connection.creation.sql_for_pending_references(
                                model, no_style(), pending_references))
                        if self.verbosity >= 1 and sql:
                            self.stdout.write("    Creating table %s\n" %
                                              model._meta.db_table)
                        for statement in sql:
                            cursor.execute(statement)
                        tables.append(
                            connection.introspection.table_name_converter(
                                model._meta.db_table))

            # We force a commit here, as that was the previous behavior.
            # If you can prove we don't need this, remove it.
            transaction.set_dirty(using=connection.alias)
        finally:
            cursor.close()

        # The connection may have been closed by a syncdb handler.
        cursor = connection.cursor()
        try:
            # Install custom SQL for the app (but only if this
            # is a model we've just created)
            if self.verbosity >= 1:
                self.stdout.write("  Installing custom SQL...\n")
            for app_name, model_list in manifest.items():
                for model in model_list:
                    if model in created_models:
                        custom_sql = custom_sql_for_model(
                            model, no_style(), connection)
                        if custom_sql:
                            if self.verbosity >= 2:
                                self.stdout.write(
                                    "    Installing custom SQL for %s.%s model\n"
                                    % (app_name, model._meta.object_name))
                            try:
                                with transaction.commit_on_success_unless_managed(
                                        using=connection.alias):
                                    for sql in custom_sql:
                                        cursor.execute(sql)
                            except Exception as e:
                                self.stderr.write(
                                    "    Failed to install custom SQL for %s.%s model: %s\n"
                                    % (app_name, model._meta.object_name, e))
                                if self.show_traceback:
                                    traceback.print_exc()
                        else:
                            if self.verbosity >= 3:
                                self.stdout.write(
                                    "    No custom SQL for %s.%s model\n" %
                                    (app_name, model._meta.object_name))

            if self.verbosity >= 1:
                self.stdout.write("  Installing indexes...\n")

            # Install SQL indices for all newly created models
            for app_name, model_list in manifest.items():
                for model in model_list:
                    if model in created_models:
                        index_sql = connection.creation.sql_indexes_for_model(
                            model, no_style())
                        if index_sql:
                            if self.verbosity >= 2:
                                self.stdout.write(
                                    "    Installing index for %s.%s model\n" %
                                    (app_name, model._meta.object_name))
                            try:
                                with transaction.commit_on_success_unless_managed(
                                        using=connection.alias):
                                    for sql in index_sql:
                                        cursor.execute(sql)
                            except Exception as e:
                                self.stderr.write(
                                    "    Failed to install index for %s.%s model: %s\n"
                                    % (app_name, model._meta.object_name, e))
        finally:
            cursor.close()

        # Load initial_data fixtures (unless that has been disabled)
        if self.load_initial_data:
            for app_label in app_labels:
                call_command('loaddata',
                             'initial_data',
                             verbosity=self.verbosity,
                             database=connection.alias,
                             skip_validation=True,
                             app_label=app_label,
                             hide_empty=True)

        return created_models
Пример #35
0
    def sync_apps(self, connection, app_labels):
        "Runs the old syncdb-style operation on a list of app_labels."
        cursor = connection.cursor()

        try:
            # Get a list of already installed *models* so that references work right.
            tables = connection.introspection.table_names(cursor)
            seen_models = connection.introspection.installed_models(tables)
            created_models = set()
            pending_references = {}

            # Build the manifest of apps and models that are to be synchronized
            all_models = [
                (app_config.label,
                    router.get_migratable_models(app_config, connection.alias, include_auto_created=True))
                for app_config in apps.get_app_configs()
                if app_config.models_module is not None and app_config.label in app_labels
            ]

            def model_installed(model):
                opts = model._meta
                converter = connection.introspection.table_name_converter
                # Note that if a model is unmanaged we short-circuit and never try to install it
                return not ((converter(opts.db_table) in tables) or
                    (opts.auto_created and converter(opts.auto_created._meta.db_table) in tables))

            manifest = OrderedDict(
                (app_name, list(filter(model_installed, model_list)))
                for app_name, model_list in all_models
            )

            create_models = set(itertools.chain(*manifest.values()))
            emit_pre_migrate_signal(create_models, self.verbosity, self.interactive, connection.alias)

            # Create the tables for each model
            if self.verbosity >= 1:
                self.stdout.write("  Creating tables...\n")
            with transaction.atomic(using=connection.alias, savepoint=connection.features.can_rollback_ddl):
                for app_name, model_list in manifest.items():
                    for model in model_list:
                        # Create the model's database table, if it doesn't already exist.
                        if self.verbosity >= 3:
                            self.stdout.write(
                                "    Processing %s.%s model\n" % (app_name, model._meta.object_name)
                            )
                        sql, references = connection.creation.sql_create_model(model, no_style(), seen_models)
                        seen_models.add(model)
                        created_models.add(model)
                        for refto, refs in references.items():
                            pending_references.setdefault(refto, []).extend(refs)
                            if refto in seen_models:
                                sql.extend(
                                    connection.creation.sql_for_pending_references(
                                        refto, no_style(), pending_references,
                                    )
                                )
                        sql.extend(
                            connection.creation.sql_for_pending_references(
                                model, no_style(), pending_references
                            )
                        )
                        if self.verbosity >= 1 and sql:
                            self.stdout.write("    Creating table %s\n" % model._meta.db_table)
                        for statement in sql:
                            cursor.execute(statement)
                        tables.append(connection.introspection.table_name_converter(model._meta.db_table))
        finally:
            cursor.close()

        # The connection may have been closed by a syncdb handler.
        cursor = connection.cursor()
        try:
            # Install custom SQL for the app (but only if this
            # is a model we've just created)
            if self.verbosity >= 1:
                self.stdout.write("  Installing custom SQL...\n")
            for app_name, model_list in manifest.items():
                for model in model_list:
                    if model in created_models:
                        custom_sql = custom_sql_for_model(model, no_style(), connection)
                        if custom_sql:
                            if self.verbosity >= 2:
                                self.stdout.write(
                                    "    Installing custom SQL for %s.%s model\n" %
                                    (app_name, model._meta.object_name)
                                )
                            try:
                                with transaction.atomic(using=connection.alias):
                                    for sql in custom_sql:
                                        cursor.execute(sql)
                            except Exception as e:
                                self.stderr.write(
                                    "    Failed to install custom SQL for %s.%s model: %s\n"
                                    % (app_name, model._meta.object_name, e)
                                )
                                if self.show_traceback:
                                    traceback.print_exc()
                        else:
                            if self.verbosity >= 3:
                                self.stdout.write(
                                    "    No custom SQL for %s.%s model\n" %
                                    (app_name, model._meta.object_name)
                                )

            if self.verbosity >= 1:
                self.stdout.write("  Installing indexes...\n")

            # Install SQL indices for all newly created models
            for app_name, model_list in manifest.items():
                for model in model_list:
                    if model in created_models:
                        index_sql = connection.creation.sql_indexes_for_model(model, no_style())
                        if index_sql:
                            if self.verbosity >= 2:
                                self.stdout.write(
                                    "    Installing index for %s.%s model\n" %
                                    (app_name, model._meta.object_name)
                                )
                            savepoint = connection.features.can_rollback_ddl
                            try:
                                with transaction.atomic(using=connection.alias, savepoint=savepoint):
                                    for sql in index_sql:
                                        cursor.execute(sql)
                            except Exception as e:
                                self.stderr.write(
                                    "    Failed to install index for %s.%s model: %s\n" %
                                    (app_name, model._meta.object_name, e)
                                )
        finally:
            cursor.close()

        # Load initial_data fixtures (unless that has been disabled)
        if self.load_initial_data:
            for app_label in app_labels:
                call_command(
                    'loaddata', 'initial_data', verbosity=self.verbosity,
                    database=connection.alias, skip_validation=True,
                    app_label=app_label, hide_empty=True,
                )

        return created_models
Пример #36
0
from collections import namedtuple