From cdf7f90f95022002464faede7f0a75fb11d10ecb Mon Sep 17 00:00:00 2001 From: Claude Paroz Date: Thu, 14 May 2015 19:27:31 +0200 Subject: [1.8.x] Fixed #24791 -- Added fallback when 'postgres' database isn't available Thanks Carl Meyer and Tim Graham for the reviews. Backport of 322605035 from master. --- django/db/backends/base/creation.py | 2 +- django/db/backends/postgresql_psycopg2/base.py | 26 ++++++++++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) (limited to 'django') diff --git a/django/db/backends/base/creation.py b/django/db/backends/base/creation.py index 1b05a1cb1a..2c803e5539 100644 --- a/django/db/backends/base/creation.py +++ b/django/db/backends/base/creation.py @@ -514,7 +514,7 @@ class BaseDatabaseCreation(object): # ourselves. Connect to the previous database (not the test database) # to do so, because it's not allowed to delete a database while being # connected to it. - with self._nodb_connection.cursor() as cursor: + with self.connection._nodb_connection.cursor() as cursor: # Wait to avoid "database is being accessed by other users" errors. time.sleep(1) cursor.execute("DROP DATABASE %s" diff --git a/django/db/backends/postgresql_psycopg2/base.py b/django/db/backends/postgresql_psycopg2/base.py index d110b120d7..a76ca3c0df 100644 --- a/django/db/backends/postgresql_psycopg2/base.py +++ b/django/db/backends/postgresql_psycopg2/base.py @@ -4,10 +4,14 @@ PostgreSQL database backend for Django. Requires psycopg 2: http://initd.org/projects/psycopg2 """ +import warnings + from django.conf import settings from django.core.exceptions import ImproperlyConfigured +from django.db import DEFAULT_DB_ALIAS from django.db.backends.base.base import BaseDatabaseWrapper from django.db.backends.base.validation import BaseDatabaseValidation +from django.db.utils import DatabaseError as WrappedDatabaseError from django.utils.encoding import force_str from django.utils.functional import cached_property from django.utils.safestring import SafeBytes, SafeText @@ -230,6 +234,28 @@ class DatabaseWrapper(BaseDatabaseWrapper): else: return True + @cached_property + def _nodb_connection(self): + nodb_connection = super(DatabaseWrapper, self)._nodb_connection + try: + nodb_connection.ensure_connection() + except (DatabaseError, WrappedDatabaseError): + warnings.warn( + "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 default database instead.", + RuntimeWarning + ) + settings_dict = self.settings_dict.copy() + settings_dict['NAME'] = settings.DATABASES[DEFAULT_DB_ALIAS]['NAME'] + nodb_connection = self.__class__( + self.settings_dict.copy(), + alias=self.alias, + allow_thread_sharing=False) + return nodb_connection + @cached_property def psycopg2_version(self): return PSYCOPG2_VERSION -- cgit v1.3