[3.1.x] Fixed #32403 -- Fixed re-raising DatabaseErrors when using only 'postgres' database.
Thanks Kazantcev Andrey for the report. Regression inf48f671223
. Backport off131841c60
from master
This commit is contained in:
parent
2d560af8fb
commit
9efe832ee1
|
@ -320,6 +320,9 @@ class DatabaseWrapper(BaseDatabaseWrapper):
|
|||
yield cursor
|
||||
finally:
|
||||
conn.close()
|
||||
break
|
||||
else:
|
||||
raise
|
||||
|
||||
@cached_property
|
||||
def pg_version(self):
|
||||
|
|
|
@ -9,4 +9,6 @@ Django 3.1.7 fixes several bugs in 3.1.6.
|
|||
Bugfixes
|
||||
========
|
||||
|
||||
* ...
|
||||
* Fixed a regression in Django 3.1 that caused ``RuntimeError`` instead of
|
||||
connection errors when using only the ``'postgres'`` database
|
||||
(:ticket:`32403`).
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
import copy
|
||||
import unittest
|
||||
from io import StringIO
|
||||
from unittest import mock
|
||||
|
||||
from django.core.exceptions import ImproperlyConfigured
|
||||
from django.db import DatabaseError, connection, connections
|
||||
from django.db import DEFAULT_DB_ALIAS, DatabaseError, connection, connections
|
||||
from django.db.backends.base.base import BaseDatabaseWrapper
|
||||
from django.test import TestCase, override_settings
|
||||
|
||||
|
@ -54,6 +55,53 @@ class Tests(TestCase):
|
|||
self.assertIsNone(cursor.db.connection)
|
||||
self.assertIsNotNone(cursor.db.settings_dict['NAME'])
|
||||
self.assertEqual(cursor.db.settings_dict['NAME'], connections['other'].settings_dict['NAME'])
|
||||
# Cursor is yielded only for the first PostgreSQL database.
|
||||
with self.assertWarnsMessage(RuntimeWarning, msg):
|
||||
with mock.patch(
|
||||
'django.db.backends.base.base.BaseDatabaseWrapper.connect',
|
||||
side_effect=mocked_connect,
|
||||
autospec=True,
|
||||
):
|
||||
with connection._nodb_cursor() as cursor:
|
||||
self.assertIs(cursor.closed, False)
|
||||
self.assertIsNotNone(cursor.db.connection)
|
||||
|
||||
def test_nodb_cursor_raises_postgres_authentication_failure(self):
|
||||
"""
|
||||
_nodb_cursor() re-raises authentication failure to the 'postgres' db
|
||||
when other connection to the PostgreSQL database isn't available.
|
||||
"""
|
||||
def mocked_connect(self):
|
||||
raise DatabaseError()
|
||||
|
||||
def mocked_all(self):
|
||||
test_connection = copy.copy(connections[DEFAULT_DB_ALIAS])
|
||||
test_connection.settings_dict = copy.deepcopy(connection.settings_dict)
|
||||
test_connection.settings_dict['NAME'] = 'postgres'
|
||||
return [test_connection]
|
||||
|
||||
msg = (
|
||||
"Normally Django will use a connection to the 'postgres' database "
|
||||
"to avoid running initialization queries against the production "
|
||||
"database when it's not needed (for example, when running tests). "
|
||||
"Django was unable to create a connection to the 'postgres' "
|
||||
"database and will use the first PostgreSQL database instead."
|
||||
)
|
||||
with self.assertWarnsMessage(RuntimeWarning, msg):
|
||||
mocker_connections_all = mock.patch(
|
||||
'django.utils.connection.BaseConnectionHandler.all',
|
||||
side_effect=mocked_all,
|
||||
autospec=True,
|
||||
)
|
||||
mocker_connect = mock.patch(
|
||||
'django.db.backends.base.base.BaseDatabaseWrapper.connect',
|
||||
side_effect=mocked_connect,
|
||||
autospec=True,
|
||||
)
|
||||
with mocker_connections_all, mocker_connect:
|
||||
with self.assertRaises(DatabaseError):
|
||||
with connection._nodb_cursor():
|
||||
pass
|
||||
|
||||
def test_database_name_too_long(self):
|
||||
from django.db.backends.postgresql.base import DatabaseWrapper
|
||||
|
|
Loading…
Reference in New Issue