Refs #24791 -- Made PostgreSQL's nodb connection use first PostgresSQL db when 'postgres' db isn't available.

Thanks Tim Graham and Claude Paroz for reviews.
This commit is contained in:
Mariusz Felisiak 2018-04-03 22:21:47 +02:00 committed by GitHub
parent b2678468ae
commit 816b386d41
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 18 additions and 13 deletions

View File

@ -9,7 +9,7 @@ import warnings
from django.conf import settings from django.conf import settings
from django.core.exceptions import ImproperlyConfigured from django.core.exceptions import ImproperlyConfigured
from django.db import DEFAULT_DB_ALIAS from django.db import connections
from django.db.backends.base.base import BaseDatabaseWrapper from django.db.backends.base.base import BaseDatabaseWrapper
from django.db.utils import DatabaseError as WrappedDatabaseError from django.db.utils import DatabaseError as WrappedDatabaseError
from django.utils.functional import cached_property from django.utils.functional import cached_property
@ -255,13 +255,13 @@ class DatabaseWrapper(BaseDatabaseWrapper):
"to avoid running initialization queries against the production " "to avoid running initialization queries against the production "
"database when it's not needed (for example, when running tests). " "database when it's not needed (for example, when running tests). "
"Django was unable to create a connection to the 'postgres' database " "Django was unable to create a connection to the 'postgres' database "
"and will use the default database instead.", "and will use the first PostgreSQL database instead.",
RuntimeWarning RuntimeWarning
) )
settings_dict = self.settings_dict.copy() for connection in connections.all():
settings_dict['NAME'] = settings.DATABASES[DEFAULT_DB_ALIAS]['NAME'] if connection.vendor == 'postgresql' and connection.settings_dict['NAME'] != 'postgres':
nodb_connection = self.__class__( return self.__class__(
self.settings_dict.copy(), {**self.settings_dict, 'NAME': connection.settings_dict['NAME']},
alias=self.alias, alias=self.alias,
allow_thread_sharing=False, allow_thread_sharing=False,
) )

View File

@ -2,7 +2,7 @@ import unittest
import warnings import warnings
from unittest import mock from unittest import mock
from django.db import DatabaseError, connection from django.db import DatabaseError, connection, connections
from django.test import TestCase from django.test import TestCase
@ -26,10 +26,15 @@ class Tests(TestCase):
with warnings.catch_warnings(record=True) as w: with warnings.catch_warnings(record=True) as w:
with mock.patch('django.db.backends.base.base.BaseDatabaseWrapper.connect', with mock.patch('django.db.backends.base.base.BaseDatabaseWrapper.connect',
side_effect=mocked_connect, autospec=True): side_effect=mocked_connect, autospec=True):
with mock.patch.object(
connection,
'settings_dict',
{**connection.settings_dict, 'NAME': 'postgres'},
):
warnings.simplefilter('always', RuntimeWarning) warnings.simplefilter('always', RuntimeWarning)
nodb_conn = connection._nodb_connection nodb_conn = connection._nodb_connection
self.assertIsNotNone(nodb_conn.settings_dict['NAME']) self.assertIsNotNone(nodb_conn.settings_dict['NAME'])
self.assertEqual(nodb_conn.settings_dict['NAME'], connection.settings_dict['NAME']) self.assertEqual(nodb_conn.settings_dict['NAME'], connections['other'].settings_dict['NAME'])
# Check a RuntimeWarning has been emitted # Check a RuntimeWarning has been emitted
self.assertEqual(len(w), 1) self.assertEqual(len(w), 1)
self.assertEqual(w[0].message.__class__, RuntimeWarning) self.assertEqual(w[0].message.__class__, RuntimeWarning)