mirror of https://github.com/django/django.git
Changed Oracle's test-database-creation to use an explicit main-db-connection
rather than just relying on manipulation of settings to determine which invocation of connection.cursor() opens a connection to the test database and which opens a connection to the main database. Thanks Aymeric Augustin for motivation and Tim Graham for review.
This commit is contained in:
parent
8b7bd62ae5
commit
abd7e48af7
|
@ -4,6 +4,7 @@ import time
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.db.backends.base.creation import BaseDatabaseCreation
|
from django.db.backends.base.creation import BaseDatabaseCreation
|
||||||
from django.db.utils import DatabaseError
|
from django.db.utils import DatabaseError
|
||||||
|
from django.utils.functional import cached_property
|
||||||
from django.utils.six.moves import input
|
from django.utils.six.moves import input
|
||||||
|
|
||||||
TEST_DATABASE_PREFIX = 'test_'
|
TEST_DATABASE_PREFIX = 'test_'
|
||||||
|
@ -12,9 +13,26 @@ PASSWORD = 'Im_a_lumberjack'
|
||||||
|
|
||||||
class DatabaseCreation(BaseDatabaseCreation):
|
class DatabaseCreation(BaseDatabaseCreation):
|
||||||
|
|
||||||
|
@cached_property
|
||||||
|
def _maindb_connection(self):
|
||||||
|
"""
|
||||||
|
This is analogous to other backends' `_nodb_connection` property,
|
||||||
|
which allows access to an "administrative" connection which can
|
||||||
|
be used to manage the test databases.
|
||||||
|
For Oracle, the only connection that can be used for that purpose
|
||||||
|
is the main (non-test) connection.
|
||||||
|
"""
|
||||||
|
settings_dict = settings.DATABASES[self.connection.alias]
|
||||||
|
user = settings_dict.get('SAVED_USER') or settings_dict['USER']
|
||||||
|
password = settings_dict.get('SAVED_PASSWORD') or settings_dict['PASSWORD']
|
||||||
|
settings_dict = settings_dict.copy()
|
||||||
|
settings_dict.update(USER=user, PASSWORD=password)
|
||||||
|
DatabaseWrapper = type(self.connection)
|
||||||
|
return DatabaseWrapper(settings_dict, alias=self.connection.alias)
|
||||||
|
|
||||||
def _create_test_db(self, verbosity=1, autoclobber=False, keepdb=False):
|
def _create_test_db(self, verbosity=1, autoclobber=False, keepdb=False):
|
||||||
parameters = self._get_test_db_params()
|
parameters = self._get_test_db_params()
|
||||||
cursor = self.connection.cursor()
|
cursor = self._maindb_connection.cursor()
|
||||||
if self._test_database_create():
|
if self._test_database_create():
|
||||||
try:
|
try:
|
||||||
self._execute_test_db_creation(cursor, parameters, verbosity)
|
self._execute_test_db_creation(cursor, parameters, verbosity)
|
||||||
|
@ -79,8 +97,18 @@ class DatabaseCreation(BaseDatabaseCreation):
|
||||||
print("Tests cancelled.")
|
print("Tests cancelled.")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
self.connection.close() # done with main user -- test user and tablespaces created
|
self._maindb_connection.close() # done with main user -- test user and tablespaces created
|
||||||
|
self._switch_to_test_user(parameters)
|
||||||
|
return self.connection.settings_dict['NAME']
|
||||||
|
|
||||||
|
def _switch_to_test_user(self, parameters):
|
||||||
|
"""
|
||||||
|
Oracle doesn't have the concept of separate databases under the same user.
|
||||||
|
Thus, we use a separate user (see _create_test_db). This method is used
|
||||||
|
to switch to that user. We will need the main user again for clean-up when
|
||||||
|
we end testing, so we keep its credentials in SAVED_USER/SAVED_PASSWORD
|
||||||
|
entries in the settings dict.
|
||||||
|
"""
|
||||||
real_settings = settings.DATABASES[self.connection.alias]
|
real_settings = settings.DATABASES[self.connection.alias]
|
||||||
real_settings['SAVED_USER'] = self.connection.settings_dict['SAVED_USER'] = \
|
real_settings['SAVED_USER'] = self.connection.settings_dict['SAVED_USER'] = \
|
||||||
self.connection.settings_dict['USER']
|
self.connection.settings_dict['USER']
|
||||||
|
@ -92,8 +120,6 @@ class DatabaseCreation(BaseDatabaseCreation):
|
||||||
self.connection.settings_dict['USER'] = parameters['user']
|
self.connection.settings_dict['USER'] = parameters['user']
|
||||||
real_settings['PASSWORD'] = self.connection.settings_dict['PASSWORD'] = parameters['password']
|
real_settings['PASSWORD'] = self.connection.settings_dict['PASSWORD'] = parameters['password']
|
||||||
|
|
||||||
return self.connection.settings_dict['NAME']
|
|
||||||
|
|
||||||
def set_as_test_mirror(self, primary_settings_dict):
|
def set_as_test_mirror(self, primary_settings_dict):
|
||||||
"""
|
"""
|
||||||
Set this database up to be used in testing as a mirror of a primary database
|
Set this database up to be used in testing as a mirror of a primary database
|
||||||
|
@ -144,8 +170,9 @@ class DatabaseCreation(BaseDatabaseCreation):
|
||||||
"""
|
"""
|
||||||
self.connection.settings_dict['USER'] = self.connection.settings_dict['SAVED_USER']
|
self.connection.settings_dict['USER'] = self.connection.settings_dict['SAVED_USER']
|
||||||
self.connection.settings_dict['PASSWORD'] = self.connection.settings_dict['SAVED_PASSWORD']
|
self.connection.settings_dict['PASSWORD'] = self.connection.settings_dict['SAVED_PASSWORD']
|
||||||
|
self.connection.close()
|
||||||
parameters = self._get_test_db_params()
|
parameters = self._get_test_db_params()
|
||||||
cursor = self.connection.cursor()
|
cursor = self._maindb_connection.cursor()
|
||||||
time.sleep(1) # To avoid "database is being accessed by other users" errors.
|
time.sleep(1) # To avoid "database is being accessed by other users" errors.
|
||||||
if self._test_user_create():
|
if self._test_user_create():
|
||||||
if verbosity >= 1:
|
if verbosity >= 1:
|
||||||
|
@ -155,7 +182,7 @@ class DatabaseCreation(BaseDatabaseCreation):
|
||||||
if verbosity >= 1:
|
if verbosity >= 1:
|
||||||
print('Destroying test database tables...')
|
print('Destroying test database tables...')
|
||||||
self._execute_test_db_destruction(cursor, parameters, verbosity)
|
self._execute_test_db_destruction(cursor, parameters, verbosity)
|
||||||
self.connection.close()
|
self._maindb_connection.close()
|
||||||
|
|
||||||
def _execute_test_db_creation(self, cursor, parameters, verbosity):
|
def _execute_test_db_creation(self, cursor, parameters, verbosity):
|
||||||
if verbosity >= 2:
|
if verbosity >= 2:
|
||||||
|
|
Loading…
Reference in New Issue