From 8eb56f3c786b4dd7f78a60145ae2e483e24b62c1 Mon Sep 17 00:00:00 2001 From: Lex Berezhny Date: Fri, 18 Nov 2016 17:36:34 -0500 Subject: [PATCH] Fixed #27507 -- Used SchemaEditor.execute() to run deferred_sql in migrate's sync_apps(). --- django/core/management/commands/migrate.py | 5 +++-- .../unmigrated_app_syncdb/__init__.py | 0 .../unmigrated_app_syncdb/models.py | 9 +++++++++ tests/migrations/test_commands.py | 15 +++++++++++++++ 4 files changed, 27 insertions(+), 2 deletions(-) create mode 100644 tests/migrations/migrations_test_apps/unmigrated_app_syncdb/__init__.py create mode 100644 tests/migrations/migrations_test_apps/unmigrated_app_syncdb/models.py diff --git a/django/core/management/commands/migrate.py b/django/core/management/commands/migrate.py index 6846b33d2ac..317c42acf70 100644 --- a/django/core/management/commands/migrate.py +++ b/django/core/management/commands/migrate.py @@ -312,8 +312,9 @@ class Command(BaseCommand): if self.verbosity >= 1: self.stdout.write(" Running deferred SQL...\n") - for statement in deferred_sql: - cursor.execute(statement) + with connection.schema_editor() as editor: + for statement in deferred_sql: + editor.execute(statement) finally: cursor.close() diff --git a/tests/migrations/migrations_test_apps/unmigrated_app_syncdb/__init__.py b/tests/migrations/migrations_test_apps/unmigrated_app_syncdb/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/migrations/migrations_test_apps/unmigrated_app_syncdb/models.py b/tests/migrations/migrations_test_apps/unmigrated_app_syncdb/models.py new file mode 100644 index 00000000000..9f3179cd0d6 --- /dev/null +++ b/tests/migrations/migrations_test_apps/unmigrated_app_syncdb/models.py @@ -0,0 +1,9 @@ +from django.db import models + + +class Classroom(models.Model): + pass + + +class Lesson(models.Model): + classroom = models.ForeignKey(Classroom, on_delete=models.CASCADE) diff --git a/tests/migrations/test_commands.py b/tests/migrations/test_commands.py index d329e50933f..3ec3cfed1d7 100644 --- a/tests/migrations/test_commands.py +++ b/tests/migrations/test_commands.py @@ -12,6 +12,7 @@ from django.core.management import CommandError, call_command from django.db import ( ConnectionHandler, DatabaseError, connection, connections, models, ) +from django.db.backends.base.schema import BaseDatabaseSchemaEditor from django.db.migrations.exceptions import ( InconsistentMigrationHistory, MigrationSchemaMissing, ) @@ -461,6 +462,20 @@ class MigrateTests(MigrationTestBase): # to avoid problems in subsequent tests. del apps._pending_operations[('migrations', 'tribble')] + @override_settings(INSTALLED_APPS=['migrations.migrations_test_apps.unmigrated_app_syncdb']) + def test_migrate_syncdb_deferred_sql_executed_with_schemaeditor(self): + """ + For an app without migrations, editor.execute() is used for executing + the syncdb deferred SQL. + """ + with mock.patch.object(BaseDatabaseSchemaEditor, 'execute') as execute: + call_command('migrate', run_syncdb=True, verbosity=0) + create_table_count = len([call for call in execute.mock_calls if 'CREATE TABLE' in str(call)]) + self.assertEqual(create_table_count, 2) + # There's at least one deferred SQL for creating the foreign key + # index. + self.assertGreater(len(execute.mock_calls), 2) + @override_settings(MIGRATION_MODULES={"migrations": "migrations.test_migrations_squashed"}) def test_migrate_record_replaced(self): """