From 9a88c6dd6aa84a1b35e585faa0058a0996cc7ed7 Mon Sep 17 00:00:00 2001 From: Sergey Fedoseev Date: Fri, 26 Oct 2018 04:37:41 +0500 Subject: [PATCH] Fixed #29827 -- Fixed reuse of test databases with --keepdb on MySQL. Regression in e1253bc26facfa1d0fca161f43925e99c2591ced. --- django/db/backends/mysql/creation.py | 17 ++++++----------- docs/releases/2.1.3.txt | 3 +++ tests/backends/mysql/test_creation.py | 7 +++++++ 3 files changed, 16 insertions(+), 11 deletions(-) diff --git a/django/db/backends/mysql/creation.py b/django/db/backends/mysql/creation.py index dbe05526daf..43456adfdda 100644 --- a/django/db/backends/mysql/creation.py +++ b/django/db/backends/mysql/creation.py @@ -19,17 +19,7 @@ class DatabaseCreation(BaseDatabaseCreation): def _execute_create_test_db(self, cursor, parameters, keepdb=False): try: - if keepdb: - # If the database should be kept, add "IF NOT EXISTS" to avoid - # "database exists" error, also temporarily disable "database - # exists" warning. - cursor.execute(''' - SET @_tmp_sql_notes := @@sql_notes, sql_notes = 0; - CREATE DATABASE IF NOT EXISTS %(dbname)s %(suffix)s; - SET sql_notes = @_tmp_sql_notes; - ''' % parameters) - else: - super()._execute_create_test_db(cursor, parameters, keepdb) + super()._execute_create_test_db(cursor, parameters, keepdb) except Exception as e: if len(e.args) < 1 or e.args[0] != 1007: # All errors except "database exists" (1007) cancel tests. @@ -49,6 +39,9 @@ class DatabaseCreation(BaseDatabaseCreation): try: self._execute_create_test_db(cursor, test_db_params, keepdb) except Exception: + if keepdb: + # If the database should be kept, skip everything else. + return try: if verbosity >= 1: self.log('Destroying old test database for alias %s…' % ( @@ -59,7 +52,9 @@ class DatabaseCreation(BaseDatabaseCreation): except Exception as e: self.log('Got an error recreating the test database: %s' % e) sys.exit(2) + self._clone_db(source_database_name, target_database_name) + def _clone_db(self, source_database_name, target_database_name): dump_cmd = DatabaseClient.settings_to_cmd_args(self.connection.settings_dict) dump_cmd[0] = 'mysqldump' dump_cmd[-1] = source_database_name diff --git a/docs/releases/2.1.3.txt b/docs/releases/2.1.3.txt index 7e0446219ea..bebd696d05c 100644 --- a/docs/releases/2.1.3.txt +++ b/docs/releases/2.1.3.txt @@ -14,3 +14,6 @@ Bugfixes * Fixed a regression in Django 1.11 where ``django-admin shell`` may hang on startup (:ticket:`29774`). + +* Fixed a regression in Django 2.0 where test databases aren't reused with + ``manage.py test --keepdb`` on MySQL (:ticket:`29827`). diff --git a/tests/backends/mysql/test_creation.py b/tests/backends/mysql/test_creation.py index e3a83346fed..2f6351d9bc6 100644 --- a/tests/backends/mysql/test_creation.py +++ b/tests/backends/mysql/test_creation.py @@ -43,3 +43,10 @@ class DatabaseCreationTests(SimpleTestCase): with self.patch_test_db_creation(self._execute_raise_access_denied): with self.assertRaises(SystemExit): creation._create_test_db(verbosity=0, autoclobber=False, keepdb=False) + + def test_clone_test_db_database_exists(self): + creation = DatabaseCreation(connection) + with self.patch_test_db_creation(self._execute_raise_database_exists): + with mock.patch.object(DatabaseCreation, '_clone_db') as _clone_db: + creation._clone_test_db('suffix', verbosity=0, keepdb=True) + _clone_db.assert_not_called()