Ticket #16969: 16969-2.diff

File 16969-2.diff, 4.4 KB (added by Claude Paroz, 11 years ago)
  • django/db/backends/creation.py

    diff --git a/django/db/backends/creation.py b/django/db/backends/creation.py
    index e4c870c..ecd1070 100644
    a b import warnings  
    66from django.conf import settings
    77from django.db.utils import load_backend
    88from django.utils.encoding import force_bytes
     9from django.utils.functional import cached_property
    910from django.utils.six.moves import input
    1011
    1112from .utils import truncate_name
    class BaseDatabaseCreation(object):  
    2930    def __init__(self, connection):
    3031        self.connection = connection
    3132
     33    @cached_property
     34    def nodb_connection(self):
     35        """
     36        Alternative connection to be used when there is no need to access
     37        the main database, specifically for test db creation/deletion.
     38        This also prevents the production database from being exposed to
     39        potential child threads while (or after) the test database is destroyed.
     40        Refs #10868 and #17786.
     41        """
     42        settings_dict = self.connection.settings_dict.copy()
     43        settings_dict['NAME'] = None
     44        backend = load_backend(settings_dict['ENGINE'])
     45        nodb_connection = backend.DatabaseWrapper(
     46             settings_dict,
     47             alias='__no_db__',
     48             allow_thread_sharing=False)
     49        return nodb_connection
     50
    3251    @classmethod
    3352    def _digest(cls, *args):
    3453        """
    class BaseDatabaseCreation(object):  
    386405        qn = self.connection.ops.quote_name
    387406
    388407        # Create the test database and connect to it.
    389         cursor = self.connection.cursor()
     408        cursor = self.nodb_connection.cursor()
    390409        try:
    391410            cursor.execute(
    392411                "CREATE DATABASE %s %s" % (qn(test_database_name), suffix))
    class BaseDatabaseCreation(object):  
    431450            print("Destroying test database for alias '%s'%s..." % (
    432451                self.connection.alias, test_db_repr))
    433452
    434         # Temporarily use a new connection and a copy of the settings dict.
    435         # This prevents the production database from being exposed to potential
    436         # child threads while (or after) the test database is destroyed.
    437         # Refs #10868 and #17786.
    438         settings_dict = self.connection.settings_dict.copy()
    439         settings_dict['NAME'] = old_database_name
    440         backend = load_backend(settings_dict['ENGINE'])
    441         new_connection = backend.DatabaseWrapper(
    442                              settings_dict,
    443                              alias='__destroy_test_db__',
    444                              allow_thread_sharing=False)
    445         new_connection.creation._destroy_test_db(test_database_name, verbosity)
     453        self._destroy_test_db(test_database_name, verbosity)
    446454
    447455    def _destroy_test_db(self, test_database_name, verbosity):
    448456        """
    class BaseDatabaseCreation(object):  
    452460        # ourselves. Connect to the previous database (not the test database)
    453461        # to do so, because it's not allowed to delete a database while being
    454462        # connected to it.
    455         cursor = self.connection.cursor()
     463        cursor = self.nodb_connection.cursor()
    456464        # Wait to avoid "database is being accessed by other users" errors.
    457465        time.sleep(1)
    458466        cursor.execute("DROP DATABASE %s"
    459467                       % self.connection.ops.quote_name(test_database_name))
    460         self.connection.close()
    461468
    462469    def set_autocommit(self):
    463470        """
  • django/db/backends/postgresql_psycopg2/base.py

    diff --git a/django/db/backends/postgresql_psycopg2/base.py b/django/db/backends/postgresql_psycopg2/base.py
    index b22c653..cb23c33 100644
    a b class DatabaseWrapper(BaseDatabaseWrapper):  
    101101
    102102    def get_connection_params(self):
    103103        settings_dict = self.settings_dict
    104         if not settings_dict['NAME']:
     104        # None may be used to connect to the default 'postgres' db
     105        if settings_dict['NAME'] == '':
    105106            from django.core.exceptions import ImproperlyConfigured
    106107            raise ImproperlyConfigured(
    107108                "settings.DATABASES is improperly configured. "
    108109                "Please supply the NAME value.")
    109110        conn_params = {
    110             'database': settings_dict['NAME'],
     111            'database': settings_dict['NAME'] or 'postgres',
    111112        }
    112113        conn_params.update(settings_dict['OPTIONS'])
    113114        if 'autocommit' in conn_params:
Back to Top