diff --git a/django/core/management/__init__.py b/django/core/management/__init__.py index 5532a0e3e93..9b8d9ad7d3a 100644 --- a/django/core/management/__init__.py +++ b/django/core/management/__init__.py @@ -232,8 +232,7 @@ class ManagementUtility(object): elif cwords[0] in subcommands and cwords[0] != 'help': subcommand_cls = self.fetch_command(cwords[0]) # special case: add the names of installed apps to options - if cwords[0] in ('dumpdata', 'sql', 'sqlall', 'sqlclear', - 'sqlindexes', 'sqlmigrate', 'sqlsequencereset', 'test'): + if cwords[0] in ('dumpdata', 'sqlmigrate', 'sqlsequencereset', 'test'): try: app_configs = apps.get_app_configs() # Get the last part of the dotted path as the app name. diff --git a/django/core/management/commands/migrate.py b/django/core/management/commands/migrate.py index 6e5640eac24..4034f3fe5ab 100644 --- a/django/core/management/commands/migrate.py +++ b/django/core/management/commands/migrate.py @@ -93,14 +93,12 @@ class Command(BaseCommand): ) # If they supplied command line arguments, work out what they mean. - run_syncdb = False target_app_labels_only = True if options['app_label'] and options['migration_name']: app_label, migration_name = options['app_label'], options['migration_name'] if app_label not in executor.loader.migrated_apps: raise CommandError( - "App '%s' does not have migrations (you cannot selectively " - "sync unmigrated apps)" % app_label + "App '%s' does not have migrations." % app_label ) if migration_name == "zero": targets = [(app_label, None)] @@ -122,20 +120,19 @@ class Command(BaseCommand): app_label = options['app_label'] if app_label not in executor.loader.migrated_apps: raise CommandError( - "App '%s' does not have migrations (you cannot selectively " - "sync unmigrated apps)" % app_label + "App '%s' does not have migrations." % app_label ) targets = [key for key in executor.loader.graph.leaf_nodes() if key[0] == app_label] else: targets = executor.loader.graph.leaf_nodes() - run_syncdb = True plan = executor.migration_plan(targets) + run_syncdb = options.get('run_syncdb') and executor.loader.unmigrated_apps # Print some useful info if self.verbosity >= 1: self.stdout.write(self.style.MIGRATE_HEADING("Operations to perform:")) - if run_syncdb and executor.loader.unmigrated_apps: + if run_syncdb: self.stdout.write( self.style.MIGRATE_LABEL(" Synchronize unmigrated apps: ") + (", ".join(executor.loader.unmigrated_apps)) @@ -159,7 +156,7 @@ class Command(BaseCommand): emit_pre_migrate_signal(self.verbosity, self.interactive, connection.alias) # Run the syncdb phase. - if run_syncdb and executor.loader.unmigrated_apps: + if run_syncdb: if self.verbosity >= 1: self.stdout.write(self.style.MIGRATE_HEADING("Synchronizing apps without migrations:")) self.sync_apps(connection, executor.loader.unmigrated_apps) diff --git a/django/core/management/commands/sql.py b/django/core/management/commands/sql.py deleted file mode 100644 index 4308c04adc4..00000000000 --- a/django/core/management/commands/sql.py +++ /dev/null @@ -1,24 +0,0 @@ -from __future__ import unicode_literals - -from django.core.management.base import AppCommand -from django.core.management.sql import sql_create -from django.db import connections, DEFAULT_DB_ALIAS - - -class Command(AppCommand): - help = "Prints the CREATE TABLE SQL statements for the given app name(s)." - - output_transaction = True - - def add_arguments(self, parser): - super(Command, self).add_arguments(parser) - parser.add_argument('--database', default=DEFAULT_DB_ALIAS, - help='Nominates a database to print the SQL for. Defaults to the ' - '"default" database.') - - def handle_app_config(self, app_config, **options): - if app_config.models_module is None: - return - connection = connections[options['database']] - statements = sql_create(app_config, self.style, connection) - return '\n'.join(statements) diff --git a/django/core/management/commands/sqlall.py b/django/core/management/commands/sqlall.py deleted file mode 100644 index d58ac4bf8f0..00000000000 --- a/django/core/management/commands/sqlall.py +++ /dev/null @@ -1,24 +0,0 @@ -from __future__ import unicode_literals - -from django.core.management.base import AppCommand -from django.core.management.sql import sql_all -from django.db import connections, DEFAULT_DB_ALIAS - - -class Command(AppCommand): - help = "Prints the CREATE TABLE and CREATE INDEX SQL statements for the given model module name(s)." - - output_transaction = True - - def add_arguments(self, parser): - super(Command, self).add_arguments(parser) - parser.add_argument('--database', default=DEFAULT_DB_ALIAS, - help='Nominates a database to print the SQL for. Defaults to the ' - '"default" database.') - - def handle_app_config(self, app_config, **options): - if app_config.models_module is None: - return - connection = connections[options['database']] - statements = sql_all(app_config, self.style, connection) - return '\n'.join(statements) diff --git a/django/core/management/commands/sqlclear.py b/django/core/management/commands/sqlclear.py deleted file mode 100644 index e2d32e96180..00000000000 --- a/django/core/management/commands/sqlclear.py +++ /dev/null @@ -1,24 +0,0 @@ -from __future__ import unicode_literals - -from django.core.management.base import AppCommand -from django.core.management.sql import sql_delete -from django.db import connections, DEFAULT_DB_ALIAS - - -class Command(AppCommand): - help = "Prints the DROP TABLE SQL statements for the given app name(s)." - - output_transaction = True - - def add_arguments(self, parser): - super(Command, self).add_arguments(parser) - parser.add_argument('--database', default=DEFAULT_DB_ALIAS, - help='Nominates a database to print the SQL for. Defaults to the ' - '"default" database.') - - def handle_app_config(self, app_config, **options): - if app_config.models_module is None: - return - connection = connections[options['database']] - statements = sql_delete(app_config, self.style, connection) - return '\n'.join(statements) diff --git a/django/core/management/commands/sqldropindexes.py b/django/core/management/commands/sqldropindexes.py deleted file mode 100644 index f4789377d46..00000000000 --- a/django/core/management/commands/sqldropindexes.py +++ /dev/null @@ -1,24 +0,0 @@ -from __future__ import unicode_literals - -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)." - - output_transaction = True - - def add_arguments(self, parser): - super(Command, self).add_arguments(parser) - parser.add_argument('--database', default=DEFAULT_DB_ALIAS, - help='Nominates a database to print the SQL for. Defaults to the ' - '"default" database.') - - def handle_app_config(self, app_config, **options): - if app_config.models_module is None: - return - connection = connections[options['database']] - statements = sql_destroy_indexes(app_config, self.style, connection) - return '\n'.join(statements) diff --git a/django/core/management/commands/sqlindexes.py b/django/core/management/commands/sqlindexes.py deleted file mode 100644 index 0fbbb0cdb99..00000000000 --- a/django/core/management/commands/sqlindexes.py +++ /dev/null @@ -1,24 +0,0 @@ -from __future__ import unicode_literals - -from django.core.management.base import AppCommand -from django.core.management.sql import sql_indexes -from django.db import connections, DEFAULT_DB_ALIAS - - -class Command(AppCommand): - help = "Prints the CREATE INDEX SQL statements for the given model module name(s)." - - output_transaction = True - - def add_arguments(self, parser): - super(Command, self).add_arguments(parser) - parser.add_argument('--database', default=DEFAULT_DB_ALIAS, - help='Nominates a database to print the SQL for. Defaults to the ' - '"default" database.') - - def handle_app_config(self, app_config, **options): - if app_config.models_module is None: - return - connection = connections[options['database']] - statements = sql_indexes(app_config, self.style, connection) - return '\n'.join(statements) diff --git a/django/core/management/sql.py b/django/core/management/sql.py index f8f85a0c3da..0c86a944acf 100644 --- a/django/core/management/sql.py +++ b/django/core/management/sql.py @@ -1,120 +1,7 @@ from __future__ import unicode_literals from django.apps import apps -from django.core.management.base import CommandError -from django.db import models, router -from django.utils.version import get_docs_version - - -def check_for_migrations(app_config, connection): - # Inner import, else tests imports it too early as it needs settings - from django.db.migrations.loader import MigrationLoader - loader = MigrationLoader(connection) - if app_config.label in loader.migrated_apps: - raise CommandError( - "App '%s' has migrations. Only the sqlmigrate and sqlflush commands " - "can be used when an app has migrations." % app_config.label - ) - - -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/%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). - 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 - - -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. +from django.db import models def sql_flush(style, connection, only_django=False, reset_sequences=True, allow_cascade=False): @@ -133,39 +20,6 @@ def sql_flush(style, connection, only_django=False, reset_sequences=True, allow_ return statements -def sql_indexes(app_config, style, connection): - "Returns a list of the CREATE 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_indexes_for_model(model, style)) - return output - - -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 - - -def sql_all(app_config, style, connection): - - check_for_migrations(app_config, connection) - - "Returns a list of CREATE TABLE SQL, initial-data inserts, and CREATE INDEX SQL for the given module." - return ( - sql_create(app_config, style, connection) + - sql_indexes(app_config, style, connection) - ) - - def emit_pre_migrate_signal(verbosity, interactive, db): # Emit the pre_migrate signal for every application. for app_config in apps.get_app_configs(): diff --git a/django/db/backends/base/creation.py b/django/db/backends/base/creation.py index b3609dbb956..8780ee22ce9 100644 --- a/django/db/backends/base/creation.py +++ b/django/db/backends/base/creation.py @@ -366,6 +366,7 @@ class BaseDatabaseCreation(object): verbosity=max(verbosity - 1, 0), interactive=False, database=self.connection.alias, + run_syncdb=True, ) # We then serialize the current state of the database into a string diff --git a/docs/intro/tutorial01.txt b/docs/intro/tutorial01.txt index e94e0ed16c7..5d4eaca76cb 100644 --- a/docs/intro/tutorial01.txt +++ b/docs/intro/tutorial01.txt @@ -537,16 +537,13 @@ Now, run :djadmin:`migrate` again to create those model tables in your database: .. code-block:: bash $ python manage.py migrate - Operations to perform: - Synchronize unmigrated apps: sessions, admin, messages, auth, staticfiles, contenttypes - Apply all migrations: polls - Synchronizing apps without migrations: - Creating tables... - Installing indexes... + Apply all migrations: admin, contenttypes, polls, auth, sessions Running migrations: + Rendering model states... DONE + ... Applying polls.0001_initial... OK - + ... The :djadmin:`migrate` command takes all the migrations that haven't been applied (Django tracks which ones are applied using a special table in your diff --git a/docs/man/django-admin.1 b/docs/man/django-admin.1 index 32321b4f3ca..838953d2e29 100644 --- a/docs/man/django-admin.1 +++ b/docs/man/django-admin.1 @@ -74,22 +74,9 @@ The option forces the use of the standard Python interpreter even when IPython is installed. .TP -.BI "sql [" "app_label ..." "]" -Prints the CREATE TABLE SQL statements for the given app name(s). -.TP -.BI "sqlall [" "app_label ..." "]" -Prints the CREATE TABLE, initial\-data and CREATE INDEX SQL statements for the -given model module name(s). -.TP -.BI "sqlclear [" "app_label ..." "]" -Prints the DROP TABLE SQL statements for the given app name(s). -.TP .BI "sqlflush [" "app_label ..." "]" Prints the SQL statements that would be executed for the "flush" command. .TP -.BI "sqlindexes [" "app_label ..." "]" -Prints the CREATE INDEX SQL statements for the given model module name(s). -.TP .BI "sqlsequencereset [" "app_label ..." "]" Prints the SQL statements for resetting PostgreSQL sequences for the given app name(s). @@ -103,8 +90,7 @@ Creates a Django project directory structure for the given project name in the current directory or the optional destination. .TP .BI migrate -Runs migrations for apps containing migrations, and just creates missing tables -for apps without migrations. +Runs migrations for all apps. .TP .BI "test [" "\-\-verbosity" "] [" "\-\-failfast" "] [" "app_label ..." "]" Runs the test suite for the specified applications, or the entire project if diff --git a/docs/ref/django-admin.txt b/docs/ref/django-admin.txt index d29213c1859..6a26c573aa4 100644 --- a/docs/ref/django-admin.txt +++ b/docs/ref/django-admin.txt @@ -963,53 +963,6 @@ beyond those apps. Same as ``--list``, applied migrations are marked by an ``[X]``. For a verbosity of 2 and above, all dependencies of a migration will also be shown. -sql ------------------------------ - -.. django-admin:: sql - -Prints the CREATE TABLE 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. - -sqlall --------------------------------- - -.. django-admin:: sqlall - -Prints the CREATE TABLE and initial-data 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. - -.. versionchanged:: 1.7 - - The ``sql*`` management commands now respect the ``allow_migrate()`` method - of :setting:`DATABASE_ROUTERS`. If you have models synced to non-default - databases, use the :djadminopt:`--database` flag to get SQL for those - models (previously they would always be included in the output). - -sqlclear ----------------------------------- - -.. django-admin:: sqlclear - -Prints the DROP TABLE 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. - -sqldropindexes ----------------------------------------- - -.. 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 -------- @@ -1021,16 +974,6 @@ command. The :djadminopt:`--database` option can be used to specify the database for which to print the SQL. -sqlindexes ------------------------------------- - -.. django-admin:: sqlindexes - -Prints the CREATE 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. - sqlmigrate -------------------------------------- diff --git a/docs/ref/models/fields.txt b/docs/ref/models/fields.txt index 39d728bbceb..3fd9d0aace8 100644 --- a/docs/ref/models/fields.txt +++ b/docs/ref/models/fields.txt @@ -183,8 +183,7 @@ scenes. .. attribute:: Field.db_index -If ``True``, :djadmin:`django-admin sqlindexes ` will output a -``CREATE INDEX`` statement for this field. +If ``True``, a database index will be created for this field. ``db_tablespace`` ----------------- @@ -1120,12 +1119,6 @@ avoid the overhead of an index if you are creating a foreign key for consistency rather than joins, or if you will be creating an alternative index like a partial or multiple column index. -.. warning:: - - It is not recommended to have a ``ForeignKey`` from an app without migrations - to an app with migrations. See the :ref:`dependencies documentation - ` for more details. - Database Representation ~~~~~~~~~~~~~~~~~~~~~~~ @@ -1335,12 +1328,6 @@ which the model is related, which works exactly the same as it does for Related objects can be added, removed, or created with the field's :class:`~django.db.models.fields.related.RelatedManager`. -.. warning:: - - It is not recommended to have a ``ManyToManyField`` from an app without migrations - to an app with migrations. See the :ref:`dependencies documentation - ` for more details. - Database Representation ~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/docs/ref/settings.txt b/docs/ref/settings.txt index dfbb10c60d8..5906cd3c9fe 100644 --- a/docs/ref/settings.txt +++ b/docs/ref/settings.txt @@ -2397,9 +2397,9 @@ Default: ``[]`` In order to restore the database state between tests for ``TransactionTestCase``\s and database backends without transactions, Django -will :ref:`serialize the contents of all apps with migrations -` when it starts the test run so it can then -reload from that copy before tests that need it. +will :ref:`serialize the contents of all apps ` +when it starts the test run so it can then reload from that copy before tests +that need it. This slows down the startup time of the test runner; if you have apps that you know don't need this feature, you can add their full names in here (e.g. diff --git a/docs/releases/1.3.txt b/docs/releases/1.3.txt index 96c0315a762..47dcd5e69bf 100644 --- a/docs/releases/1.3.txt +++ b/docs/releases/1.3.txt @@ -432,8 +432,7 @@ If you have an existing project that is using the database session backend, you don't have to do anything to accommodate this change. However, you may get a significant performance boost if you manually add the new index to the session table. The SQL that will add the -index can be found by running the :djadmin:`sqlindexes` admin -command:: +index can be found by running the ``sqlindexes`` admin command:: python manage.py sqlindexes sessions diff --git a/docs/releases/1.7.txt b/docs/releases/1.7.txt index e2dc732ae2c..f7fc4163b03 100644 --- a/docs/releases/1.7.txt +++ b/docs/releases/1.7.txt @@ -74,9 +74,8 @@ but a few of the key features are: `. * It is not advised to have apps without migrations depend on (have a - :ref:`ForeignKey ` or :ref:`ManyToManyField ` to) apps with migrations. Read the - :ref:`dependencies documentation ` for more. - + :ref:`ForeignKey ` or :ref:`ManyToManyField ` + to) apps with migrations. * If you are upgrading from South, see our :ref:`upgrading-from-south` documentation, and third-party app authors should read the diff --git a/docs/spelling_wordlist b/docs/spelling_wordlist index 498f03efbdd..65f76fa0ca1 100644 --- a/docs/spelling_wordlist +++ b/docs/spelling_wordlist @@ -582,12 +582,7 @@ spam spammers spatialite Springmeyer -sql -sqlall -sqlclear -sqldropindexes sqlflush -sqlindexes sqlmigrate sqlsequencereset squashmigrations diff --git a/docs/topics/migrations.txt b/docs/topics/migrations.txt index 9c565748576..31d26cb8d79 100644 --- a/docs/topics/migrations.txt +++ b/docs/topics/migrations.txt @@ -136,12 +136,9 @@ database to make sure they work as expected:: $ python manage.py migrate Operations to perform: - Synchronize unmigrated apps: sessions, admin, messages, auth, staticfiles, contenttypes Apply all migrations: books - Synchronizing apps without migrations: - Creating tables... - Installing indexes... Running migrations: + Rendering model states... DONE Applying books.0003_auto... OK The command runs in two stages; first, it synchronizes unmigrated apps, and @@ -195,26 +192,6 @@ restrict to a single app. Restricting to a single app (either in a guarantee; any other apps that need to be used to get dependencies correct will be. -.. _unmigrated-dependencies: - -Be aware, however, that unmigrated apps cannot depend on migrated apps, by the -very nature of not having migrations. This means that it is not generally -possible to have an unmigrated app have a ``ForeignKey`` or ``ManyToManyField`` -to a migrated app; some cases may work, but it will eventually fail. - -.. warning:: - - Even if things appear to work with unmigrated apps depending on migrated - apps, Django may not generate all the necessary foreign key constraints! - -This is particularly apparent if you use swappable models (e.g. -``AUTH_USER_MODEL``), as every app that uses swappable models will need -to have migrations if you're unlucky. As time goes on, more and more -third-party apps will get migrations, but in the meantime you can either -give them migrations yourself (using :setting:`MIGRATION_MODULES` to -store those modules outside of the app's own module if you wish), or -keep the app with your user model unmigrated. - .. _migration-files: Migration files diff --git a/docs/topics/testing/tools.txt b/docs/topics/testing/tools.txt index 3fabf63c44d..9d3ae456fd3 100644 --- a/docs/topics/testing/tools.txt +++ b/docs/topics/testing/tools.txt @@ -670,12 +670,12 @@ to test the effects of commit and rollback: .. warning:: - ``TestCase`` running on a database that does not support rollback (e.g. MySQL with the - MyISAM storage engine), and all instances of ``TransactionTestCase``, will - roll back at the end of the test by deleting all data from the test database - and reloading initial data for apps without migrations. + ``TestCase`` running on a database that does not support rollback (e.g. MySQL + with the MyISAM storage engine), and all instances of ``TransactionTestCase``, + will roll back at the end of the test by deleting all data from the test + database. - Apps with migrations :ref:`will not see their data reloaded `; + Apps :ref:`will not see their data reloaded `; if you need this functionality (for example, third-party apps should enable this) you can set ``serialized_rollback = True`` inside the ``TestCase`` body. diff --git a/tests/admin_scripts/tests.py b/tests/admin_scripts/tests.py index cbe2a5e6e30..c7603e3914a 100644 --- a/tests/admin_scripts/tests.py +++ b/tests/admin_scripts/tests.py @@ -319,13 +319,6 @@ class DjangoAdminFullPathDefaultSettings(AdminScriptTestCase): self.assertNoOutput(err) self.assertOutput(out, SYSTEM_CHECK_MSG) - def test_sqlclear_builtin_with_settings(self): - "fulldefault: django-admin builtin commands succeed if a setting file is provided" - args = ['sqlclear', '--settings=test_project.settings', 'complex_app'] - out, err = self.run_django_admin(args) - self.assertNoOutput(err) - self.assertOutput(out, '-- App creates no tables in the database. Nothing to do.') - def test_builtin_with_environment(self): "fulldefault: django-admin builtin commands succeed if the environment contains settings" args = ['check', 'admin_scripts'] diff --git a/tests/bash_completion/tests.py b/tests/bash_completion/tests.py index 8b284389c0d..b12a0cecdc3 100644 --- a/tests/bash_completion/tests.py +++ b/tests/bash_completion/tests.py @@ -78,7 +78,7 @@ class BashCompletionTests(unittest.TestCase): "Subcommands can be autocompleted" self._user_input('django-admin sql') output = self._run_autocomplete() - self.assertEqual(output, ['sql sqlall sqlclear sqldropindexes sqlflush sqlindexes sqlmigrate sqlsequencereset']) + self.assertEqual(output, ['sqlflush sqlmigrate sqlsequencereset']) def test_completed_subcommand(self): "Show option flags in case a subcommand is completed" diff --git a/tests/commands_sql/__init__.py b/tests/commands_sql/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/tests/commands_sql/models.py b/tests/commands_sql/models.py deleted file mode 100644 index fe5768b3dd6..00000000000 --- a/tests/commands_sql/models.py +++ /dev/null @@ -1,11 +0,0 @@ -from django.db import models - - -class Comment(models.Model): - pass - - -class Book(models.Model): - title = models.CharField(max_length=100, db_index=True) - comments = models.ManyToManyField(Comment) - counter = models.PositiveIntegerField() diff --git a/tests/commands_sql/tests.py b/tests/commands_sql/tests.py deleted file mode 100644 index 5eb9f0191a3..00000000000 --- a/tests/commands_sql/tests.py +++ /dev/null @@ -1,111 +0,0 @@ -from __future__ import unicode_literals - -import re -import unittest - -from django.apps import apps -from django.core.management.color import no_style -from django.core.management.sql import (sql_create, sql_delete, sql_indexes, - sql_destroy_indexes, sql_all) -from django.db import connections, DEFAULT_DB_ALIAS -from django.test import TestCase, ignore_warnings, override_settings -from django.utils import six -from django.utils.deprecation import RemovedInDjango20Warning - -# See also initial_sql_regress for 'custom_sql_for_model' tests - - -class SQLCommandsTestCase(TestCase): - """Tests for several functions in django/core/management/sql.py""" - def count_ddl(self, output, cmd): - return len([o for o in output if o.startswith(cmd)]) - - def test_sql_create(self): - app_config = apps.get_app_config('commands_sql') - output = sql_create(app_config, no_style(), connections[DEFAULT_DB_ALIAS]) - - tables = set() - create_table_re = re.compile(r'^create table .(?P[\w_]+).*', re.IGNORECASE) - reference_re = re.compile(r'.* references .(?P
[\w_]+).*', re.IGNORECASE) - for statement in output: - create_table = create_table_re.match(statement) - if create_table: - # Lower since Oracle's table names are upper cased. - tables.add(create_table.group('table').lower()) - continue - reference = reference_re.match(statement) - if reference: - # Lower since Oracle's table names are upper cased. - table = reference.group('table').lower() - self.assertIn( - table, tables, "The table %s is referenced before its creation." % table - ) - - self.assertEqual(tables, { - 'commands_sql_comment', 'commands_sql_book', 'commands_sql_book_comments' - }) - - @unittest.skipUnless('PositiveIntegerField' in connections[DEFAULT_DB_ALIAS].data_type_check_constraints, 'Backend does not have checks.') - def test_sql_create_check(self): - """Regression test for #23416 -- Check that db_params['check'] is respected.""" - app_config = apps.get_app_config('commands_sql') - output = sql_create(app_config, no_style(), connections[DEFAULT_DB_ALIAS]) - success = False - for statement in output: - if 'CHECK' in statement: - success = True - if not success: - self.fail("'CHECK' not found in output %s" % output) - - def test_sql_delete(self): - app_config = apps.get_app_config('commands_sql') - output = sql_delete(app_config, no_style(), connections[DEFAULT_DB_ALIAS], close_connection=False) - drop_tables = [o for o in output if o.startswith('DROP TABLE')] - self.assertEqual(len(drop_tables), 3) - # Lower so that Oracle's upper case tbl names wont break - sql = drop_tables[-1].lower() - six.assertRegex(self, sql, r'^drop table .commands_sql_comment.*') - - @ignore_warnings(category=RemovedInDjango20Warning) - def test_sql_indexes(self): - app_config = apps.get_app_config('commands_sql') - output = sql_indexes(app_config, no_style(), connections[DEFAULT_DB_ALIAS]) - # Number of indexes is backend-dependent - self.assertTrue(1 <= self.count_ddl(output, 'CREATE INDEX') <= 4) - - def test_sql_destroy_indexes(self): - app_config = apps.get_app_config('commands_sql') - output = sql_destroy_indexes(app_config, no_style(), connections[DEFAULT_DB_ALIAS]) - # Number of indexes is backend-dependent - self.assertTrue(1 <= self.count_ddl(output, 'DROP INDEX') <= 4) - - @ignore_warnings(category=RemovedInDjango20Warning) - def test_sql_all(self): - app_config = apps.get_app_config('commands_sql') - output = sql_all(app_config, no_style(), connections[DEFAULT_DB_ALIAS]) - - self.assertEqual(self.count_ddl(output, 'CREATE TABLE'), 3) - # Number of indexes is backend-dependent - self.assertTrue(1 <= self.count_ddl(output, 'CREATE INDEX') <= 4) - - -class TestRouter(object): - def allow_migrate(self, db, model): - return False - - -@override_settings(DATABASE_ROUTERS=[TestRouter()]) -class SQLCommandsRouterTestCase(TestCase): - - def test_router_honored(self): - app_config = apps.get_app_config('commands_sql') - for sql_command in (sql_all, sql_create, sql_delete, sql_indexes, sql_destroy_indexes): - if sql_command is sql_delete: - output = sql_command(app_config, no_style(), connections[DEFAULT_DB_ALIAS], close_connection=False) - # "App creates no tables in the database. Nothing to do." - expected_output = 1 - else: - output = sql_command(app_config, no_style(), connections[DEFAULT_DB_ALIAS]) - expected_output = 0 - self.assertEqual(len(output), expected_output, - "%s command is not honoring routers" % sql_command.__name__) diff --git a/tests/commands_sql_migrations/__init__.py b/tests/commands_sql_migrations/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/tests/commands_sql_migrations/migrations/0001_initial.py b/tests/commands_sql_migrations/migrations/0001_initial.py deleted file mode 100644 index 39a53bf68f2..00000000000 --- a/tests/commands_sql_migrations/migrations/0001_initial.py +++ /dev/null @@ -1,33 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - -from django.db import models, migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ] - - operations = [ - migrations.CreateModel( - name='Comment', - fields=[ - ('id', models.AutoField(verbose_name='ID', primary_key=True, serialize=False, auto_created=True)), - ], - options={ - }, - bases=(models.Model,), - ), - migrations.CreateModel( - name='Book', - fields=[ - ('id', models.AutoField(verbose_name='ID', primary_key=True, serialize=False, auto_created=True)), - ('title', models.CharField(db_index=True, max_length=100)), - ('comments', models.ManyToManyField(to='commands_sql_migrations.Comment')), - ], - options={ - }, - bases=(models.Model,), - ), - ] diff --git a/tests/commands_sql_migrations/migrations/__init__.py b/tests/commands_sql_migrations/migrations/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/tests/commands_sql_migrations/models.py b/tests/commands_sql_migrations/models.py deleted file mode 100644 index 78ad7223075..00000000000 --- a/tests/commands_sql_migrations/models.py +++ /dev/null @@ -1,10 +0,0 @@ -from django.db import models - - -class Comment(models.Model): - pass - - -class Book(models.Model): - title = models.CharField(max_length=100, db_index=True) - comments = models.ManyToManyField(Comment) diff --git a/tests/commands_sql_migrations/tests.py b/tests/commands_sql_migrations/tests.py deleted file mode 100644 index 23b37a0f8f4..00000000000 --- a/tests/commands_sql_migrations/tests.py +++ /dev/null @@ -1,39 +0,0 @@ -from __future__ import unicode_literals - -from django.apps import apps -from django.core.management import CommandError -from django.core.management.color import no_style -from django.core.management.sql import (sql_create, sql_delete, sql_indexes, - sql_destroy_indexes, sql_all) -from django.db import connections, DEFAULT_DB_ALIAS -from django.test import TestCase - - -class SQLCommandsMigrationsTestCase(TestCase): - """Tests that apps with migrations can not use sql commands.""" - - def test_sql_create(self): - app_config = apps.get_app_config('commands_sql_migrations') - with self.assertRaises(CommandError): - sql_create(app_config, no_style(), connections[DEFAULT_DB_ALIAS]) - - def test_sql_delete(self): - app_config = apps.get_app_config('commands_sql_migrations') - with self.assertRaises(CommandError): - sql_delete(app_config, no_style(), connections[DEFAULT_DB_ALIAS], close_connection=False) - - def test_sql_indexes(self): - app_config = apps.get_app_config('commands_sql_migrations') - with self.assertRaises(CommandError): - sql_indexes(app_config, no_style(), connections[DEFAULT_DB_ALIAS]) - - def test_sql_destroy_indexes(self): - app_config = apps.get_app_config('commands_sql_migrations') - with self.assertRaises(CommandError): - sql_destroy_indexes(app_config, no_style(), - connections[DEFAULT_DB_ALIAS]) - - def test_sql_all(self): - app_config = apps.get_app_config('commands_sql_migrations') - with self.assertRaises(CommandError): - sql_all(app_config, no_style(), connections[DEFAULT_DB_ALIAS]) diff --git a/tests/model_inheritance/tests.py b/tests/model_inheritance/tests.py index 10721a6b3f5..e207fe9a847 100644 --- a/tests/model_inheritance/tests.py +++ b/tests/model_inheritance/tests.py @@ -404,7 +404,7 @@ class InheritanceSameModelNameTests(TransactionTestCase): def test_inheritance_with_same_model_name(self): with self.modify_settings( INSTALLED_APPS={'append': ['model_inheritance.same_model_name']}): - call_command('migrate', verbosity=0) + call_command('migrate', verbosity=0, run_syncdb=True) from .same_model_name.models import Copy copy = self.title.attached_same_model_name_copy_set.create( content='The Web framework for perfectionists with deadlines.', diff --git a/tests/proxy_model_inheritance/tests.py b/tests/proxy_model_inheritance/tests.py index 78e3c2607ef..3678466e8cf 100644 --- a/tests/proxy_model_inheritance/tests.py +++ b/tests/proxy_model_inheritance/tests.py @@ -22,7 +22,7 @@ class ProxyModelInheritanceTests(TransactionTestCase): def test_table_exists(self): with extend_sys_path(os.path.dirname(os.path.abspath(upath(__file__)))): with self.modify_settings(INSTALLED_APPS={'append': ['app1', 'app2']}): - call_command('migrate', verbosity=0) + call_command('migrate', verbosity=0, run_syncdb=True) from app1.models import ProxyModel from app2.models import NiceModel self.assertEqual(NiceModel.objects.all().count(), 0)