diff --git a/django/db/backends/mysql/base.py b/django/db/backends/mysql/base.py index ea687715e4..d10be94f43 100644 --- a/django/db/backends/mysql/base.py +++ b/django/db/backends/mysql/base.py @@ -284,7 +284,7 @@ class DatabaseOperations(BaseDatabaseOperations): # With MySQLdb, cursor objects have an (undocumented) "_last_executed" # attribute where the exact query sent to the database is saved. # See MySQLdb/cursors.py in the source distribution. - return force_text(cursor._last_executed, errors='replace') + return force_text(getattr(cursor, '_last_executed', None), errors='replace') def no_limit_value(self): # 2**64 - 1, as recommended by the MySQL documentation diff --git a/tests/backends/tests.py b/tests/backends/tests.py index c1a26df7fc..488f8d518b 100644 --- a/tests/backends/tests.py +++ b/tests/backends/tests.py @@ -164,6 +164,17 @@ class DateQuotingTest(TestCase): @override_settings(DEBUG=True) class LastExecutedQueryTest(TestCase): + def test_last_executed_query(self): + """ + last_executed_query should not raise an exception even if no previous + query has been run. + """ + cursor = connection.cursor() + try: + connection.ops.last_executed_query(cursor, '', ()) + except Exception: + self.fail("'last_executed_query' should not raise an exception.") + def test_debug_sql(self): list(models.Reporter.objects.filter(first_name="test")) sql = connection.queries[-1]['sql'].lower()