1
0
mirror of https://github.com/django/django.git synced 2025-07-05 10:19:20 +00:00

[soc2009/multidb] Renaming of database attributes - you now use NAME, ENGINE, etc rather than DATABASE_NAME, DATABASE_ENGINE inside DATABASES. Also deprecates the use of short names (.e.g., `sqlite3` for backends in ENGINE). Patch from Russell Keith-Magee.

Conflicts:

	docs/releases/1.2.txt

git-svn-id: http://code.djangoproject.com/svn/django/branches/soc2009/multidb@11775 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Alex Gaynor 2009-11-23 16:45:41 +00:00
parent 3e6ae729bc
commit 4e36fffab2
55 changed files with 628 additions and 425 deletions

3
TODO
View File

@ -7,9 +7,6 @@ Required for v1.2
* Finalize the sql.Query internals * Finalize the sql.Query internals
* Clean up the use of db.backend.query_class() * Clean up the use of db.backend.query_class()
* Verify it still works with GeoDjango * Verify it still works with GeoDjango
* Resolve the public facing UI issues around using multi-db
* Should we take the opportunity to modify DB backends to use fully qualified paths?
* Should we clean up DATABASES['DATABASE_NAME'] to DATABASES['NAME'] etc?
* Cleanup of new API entry points * Cleanup of new API entry points
* validate() on a field * validate() on a field
* name/purpose clash with Honza? * name/purpose clash with Honza?

View File

@ -11,16 +11,15 @@ MANAGERS = ADMINS
DATABASES = { DATABASES = {
'default': { 'default': {
'DATABASE_ENGINE': '', # 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'. 'ENGINE': 'django.db.backends.', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
'DATABASE_NAME': '', # Or path to database file if using sqlite3. 'NAME': '', # Or path to database file if using sqlite3.
'DATABASE_USER': '', # Not used with sqlite3. 'USER': '', # Not used with sqlite3.
'DATABASE_PASSWORD': '', # Not used with sqlite3. 'PASSWORD': '', # Not used with sqlite3.
'DATABASE_HOST': '', # Set to empty string for localhost. Not used with sqlite3. 'HOST': '', # Set to empty string for localhost. Not used with sqlite3.
'DATABASE_PORT': '', # Set to empty string for default. Not used with sqlite3. 'PORT': '', # Set to empty string for default. Not used with sqlite3.
} }
} }
# Local time zone for this installation. Choices can be found here: # Local time zone for this installation. Choices can be found here:
# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name # http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
# although not all choices may be available on all operating systems. # although not all choices may be available on all operating systems.

View File

@ -5,7 +5,7 @@ class USStateField(Field):
return "USStateField" return "USStateField"
def db_type(self, connection): def db_type(self, connection):
if connection.settings_dict['DATABASE_ENGINE'] == 'oracle': if connection.settings_dict['ENGINE'] == 'django.db.backends.oracle':
return 'CHAR(2)' return 'CHAR(2)'
else: else:
return 'varchar(2)' return 'varchar(2)'
@ -21,7 +21,7 @@ class PhoneNumberField(Field):
return "PhoneNumberField" return "PhoneNumberField"
def db_type(self, connection): def db_type(self, connection):
if connection.settings_dict['DATABASE_ENGINE'] == 'oracle': if connection.settings_dict['ENGINE'] == 'django.db.backends.oracle':
return 'VARCHAR2(20)' return 'VARCHAR2(20)'
else: else:
return 'varchar(20)' return 'varchar(20)'

View File

@ -49,7 +49,7 @@ class Command(NoArgsCommand):
and return each table to the state it was in after syncdb. and return each table to the state it was in after syncdb.
Are you sure you want to do this? Are you sure you want to do this?
Type 'yes' to continue, or 'no' to cancel: """ % connection.settings_dict['DATABASE_NAME']) Type 'yes' to continue, or 'no' to cancel: """ % connection.settings_dict['NAME'])
else: else:
confirm = 'yes' confirm = 'yes'
@ -65,7 +65,7 @@ class Command(NoArgsCommand):
* At least one of the expected database tables doesn't exist. * At least one of the expected database tables doesn't exist.
* The SQL was invalid. * The SQL was invalid.
Hint: Look at the output of 'django-admin.py sqlflush'. That's the SQL this command wasn't able to run. Hint: Look at the output of 'django-admin.py sqlflush'. That's the SQL this command wasn't able to run.
The full error: %s""" % (connection.settings_dict.DATABASE_NAME, e)) The full error: %s""" % (connection.settings_dict['NAME'], e))
transaction.commit_unless_managed(using=db) transaction.commit_unless_managed(using=db)
# Emit the post sync signal. This allows individual # Emit the post sync signal. This allows individual

View File

@ -35,7 +35,7 @@ This will IRREVERSIBLY DESTROY any data for
the "%s" application in the database "%s". the "%s" application in the database "%s".
Are you sure you want to do this? Are you sure you want to do this?
Type 'yes' to continue, or 'no' to cancel: """ % (app_name, connection.settings_dict['DATABASE_NAME'])) Type 'yes' to continue, or 'no' to cancel: """ % (app_name, connection.settings_dict['NAME']))
else: else:
confirm = 'yes' confirm = 'yes'

View File

@ -17,12 +17,13 @@ except NameError:
def sql_create(app, style, connection): def sql_create(app, style, connection):
"Returns a list of the CREATE TABLE SQL statements for the given app." "Returns a list of the CREATE TABLE SQL statements for the given app."
if connection.settings_dict['DATABASE_ENGINE'] == 'dummy': if connection.settings_dict['ENGINE'] == 'django.db.backends.dummy':
# This must be the "dummy" database backend, which means the user # This must be the "dummy" database backend, which means the user
# hasn't set DATABASE_ENGINE. # hasn't set ENGINE for the databse.
raise CommandError("Django doesn't know which syntax to use for your SQL statements,\n" + raise CommandError("Django doesn't know which syntax to use for your SQL statements,\n" +
"because you haven't specified the DATABASE_ENGINE setting.\n" + "because you haven't specified the ENGINE setting for the database.\n" +
"Edit your settings file and change DATABASE_ENGINE to something like 'postgresql' or 'mysql'.") "Edit your settings file and change DATBASES['default']['ENGINE'] to something like\n" +
"'django.db.backends.postgresql' or 'django.db.backends.mysql'")
# Get installed models, so we generate REFERENCES right. # Get installed models, so we generate REFERENCES right.
# We trim models from the current app so that the sqlreset command does not # We trim models from the current app so that the sqlreset command does not
@ -162,7 +163,8 @@ def custom_sql_for_model(model, style, connection):
statements = re.compile(r";[ \t]*$", re.M) statements = re.compile(r";[ \t]*$", re.M)
# Find custom SQL, if it's available. # Find custom SQL, if it's available.
sql_files = [os.path.join(app_dir, "%s.%s.sql" % (opts.object_name.lower(), connection.settings_dict['DATABASE_ENGINE'])), backend_name = connection.settings_dict['ENGINE'].split('.')[-1]
sql_files = [os.path.join(app_dir, "%s.%s.sql" % (opts.object_name.lower(), backend_name)),
os.path.join(app_dir, "%s.sql" % opts.object_name.lower())] os.path.join(app_dir, "%s.sql" % opts.object_name.lower())]
for sql_file in sql_files: for sql_file in sql_files:
if os.path.exists(sql_file): if os.path.exists(sql_file):

View File

@ -9,22 +9,31 @@ __all__ = ('backend', 'connection', 'connections', 'DatabaseError',
DEFAULT_DB_ALIAS = 'default' DEFAULT_DB_ALIAS = 'default'
if not settings.DATABASES or DEFAULT_DB_ALIAS not in settings.DATABASES: # For backwards compatibility - Port any old database settings over to
settings.DATABASES[DEFAULT_DB_ALIAS] = { # the new values.
'DATABASE_ENGINE': settings.DATABASE_ENGINE, if not settings.DATABASES:
'DATABASE_HOST': settings.DATABASE_HOST, import warnings
'DATABASE_NAME': settings.DATABASE_NAME, warnings.warn(
'DATABASE_OPTIONS': settings.DATABASE_OPTIONS, "settings.DATABASE_* is deprecated; use settings.DATABASES instead.",
'DATABASE_PASSWORD': settings.DATABASE_PASSWORD, PendingDeprecationWarning
'DATABASE_PORT': settings.DATABASE_PORT, )
'DATABASE_USER': settings.DATABASE_USER,
'TIME_ZONE': settings.TIME_ZONE,
'TEST_DATABASE_CHARSET': settings.TEST_DATABASE_CHARSET, settings.DATABASES[DEFAULT_DB_ALIAS] = {
'TEST_DATABASE_COLLATION': settings.TEST_DATABASE_COLLATION, 'ENGINE': settings.DATABASE_ENGINE,
'TEST_DATABASE_NAME': settings.TEST_DATABASE_NAME, 'HOST': settings.DATABASE_HOST,
'NAME': settings.DATABASE_NAME,
'OPTIONS': settings.DATABASE_OPTIONS,
'PASSWORD': settings.DATABASE_PASSWORD,
'PORT': settings.DATABASE_PORT,
'USER': settings.DATABASE_USER,
'TEST_CHARSET': settings.TEST_DATABASE_CHARSET,
'TEST_COLLATION': settings.TEST_DATABASE_COLLATION,
'TEST_NAME': settings.TEST_DATABASE_NAME,
} }
if DEFAULT_DB_ALIAS not in settings.DATABASES:
raise ImproperlyConfigured("You must default a '%s' database" % DEFAULT_DB_ALIAS)
connections = ConnectionHandler(settings.DATABASES) connections = ConnectionHandler(settings.DATABASES)
@ -38,7 +47,7 @@ connections = ConnectionHandler(settings.DATABASES)
# we load all these up for backwards compatibility, you should use # we load all these up for backwards compatibility, you should use
# connections['default'] instead. # connections['default'] instead.
connection = connections[DEFAULT_DB_ALIAS] connection = connections[DEFAULT_DB_ALIAS]
backend = load_backend(connection.settings_dict['DATABASE_ENGINE']) backend = load_backend(connection.settings_dict['ENGINE'])
DatabaseError = backend.DatabaseError DatabaseError = backend.DatabaseError
IntegrityError = backend.IntegrityError IntegrityError = backend.IntegrityError

View File

@ -29,9 +29,8 @@ class BaseDatabaseWrapper(local):
def __init__(self, settings_dict, alias=DEFAULT_DB_ALIAS): def __init__(self, settings_dict, alias=DEFAULT_DB_ALIAS):
# `settings_dict` should be a dictionary containing keys such as # `settings_dict` should be a dictionary containing keys such as
# DATABASE_NAME, DATABASE_USER, etc. It's called `settings_dict` # NAME, USER, etc. It's called `settings_dict` instead of `settings`
# instead of `settings` to disambiguate it from Django settings # to disambiguate it from Django settings modules.
# modules.
self.connection = None self.connection = None
self.queries = [] self.queries = []
self.settings_dict = settings_dict self.settings_dict = settings_dict

View File

@ -327,13 +327,10 @@ class BaseDatabaseCreation(object):
test_database_name = self._create_test_db(verbosity, autoclobber) test_database_name = self._create_test_db(verbosity, autoclobber)
self.connection.close() self.connection.close()
self.connection.settings_dict["DATABASE_NAME"] = test_database_name self.connection.settings_dict["NAME"] = test_database_name
can_rollback = self._rollback_works() can_rollback = self._rollback_works()
self.connection.settings_dict["DATABASE_SUPPORTS_TRANSACTIONS"] = can_rollback self.connection.settings_dict["SUPPORTS_TRANSACTIONS"] = can_rollback
# FIXME we end up loading the same fixture into the default DB for each
# DB we have, this causes various test failures, but can't really be
# fixed until we have an API for saving to a specific DB
call_command('syncdb', verbosity=verbosity, interactive=False, database=self.connection.alias) call_command('syncdb', verbosity=verbosity, interactive=False, database=self.connection.alias)
if settings.CACHE_BACKEND.startswith('db://'): if settings.CACHE_BACKEND.startswith('db://'):
@ -351,10 +348,10 @@ class BaseDatabaseCreation(object):
"Internal implementation - creates the test db tables." "Internal implementation - creates the test db tables."
suffix = self.sql_table_creation_suffix() suffix = self.sql_table_creation_suffix()
if self.connection.settings_dict['TEST_DATABASE_NAME']: if self.connection.settings_dict['TEST_NAME']:
test_database_name = self.connection.settings_dict['TEST_DATABASE_NAME'] test_database_name = self.connection.settings_dict['TEST_NAME']
else: else:
test_database_name = TEST_DATABASE_PREFIX + self.connection.settings_dict['DATABASE_NAME'] test_database_name = TEST_DATABASE_PREFIX + self.connection.settings_dict['NAME']
qn = self.connection.ops.quote_name qn = self.connection.ops.quote_name
@ -406,8 +403,8 @@ class BaseDatabaseCreation(object):
if verbosity >= 1: if verbosity >= 1:
print "Destroying test database '%s'..." % self.connection.alias print "Destroying test database '%s'..." % self.connection.alias
self.connection.close() self.connection.close()
test_database_name = self.connection.settings_dict['DATABASE_NAME'] test_database_name = self.connection.settings_dict['NAME']
self.connection.settings_dict['DATABASE_NAME'] = old_database_name self.connection.settings_dict['NAME'] = old_database_name
self._destroy_test_db(test_database_name, verbosity) self._destroy_test_db(test_database_name, verbosity)

View File

@ -1,7 +1,7 @@
""" """
Dummy database backend for Django. Dummy database backend for Django.
Django uses this if the DATABASE_ENGINE setting is empty (None or empty string). Django uses this if the database ENGINE setting is empty (None or empty string).
Each of these API functions, except connection.close(), raises Each of these API functions, except connection.close(), raises
ImproperlyConfigured. ImproperlyConfigured.
@ -12,7 +12,7 @@ from django.db.backends import *
from django.db.backends.creation import BaseDatabaseCreation from django.db.backends.creation import BaseDatabaseCreation
def complain(*args, **kwargs): def complain(*args, **kwargs):
raise ImproperlyConfigured, "You haven't set the DATABASE_ENGINE setting yet." raise ImproperlyConfigured, "You haven't set the database ENGINE setting yet."
def ignore(*args, **kwargs): def ignore(*args, **kwargs):
pass pass

View File

@ -262,22 +262,22 @@ class DatabaseWrapper(BaseDatabaseWrapper):
'use_unicode': True, 'use_unicode': True,
} }
settings_dict = self.settings_dict settings_dict = self.settings_dict
if settings_dict['DATABASE_USER']: if settings_dict['USER']:
kwargs['user'] = settings_dict['DATABASE_USER'] kwargs['user'] = settings_dict['USER']
if settings_dict['DATABASE_NAME']: if settings_dict['NAME']:
kwargs['db'] = settings_dict['DATABASE_NAME'] kwargs['db'] = settings_dict['NAME']
if settings_dict['DATABASE_PASSWORD']: if settings_dict['PASSWORD']:
kwargs['passwd'] = settings_dict['DATABASE_PASSWORD'] kwargs['passwd'] = settings_dict['PASSWORD']
if settings_dict['DATABASE_HOST'].startswith('/'): if settings_dict['HOST'].startswith('/'):
kwargs['unix_socket'] = settings_dict['DATABASE_HOST'] kwargs['unix_socket'] = settings_dict['HOST']
elif settings_dict['DATABASE_HOST']: elif settings_dict['HOST']:
kwargs['host'] = settings_dict['DATABASE_HOST'] kwargs['host'] = settings_dict['HOST']
if settings_dict['DATABASE_PORT']: if settings_dict['PORT']:
kwargs['port'] = int(settings_dict['DATABASE_PORT']) kwargs['port'] = int(settings_dict['PORT'])
# We need the number of potentially affected rows after an # We need the number of potentially affected rows after an
# "UPDATE", not the number of changed rows. # "UPDATE", not the number of changed rows.
kwargs['client_flag'] = CLIENT.FOUND_ROWS kwargs['client_flag'] = CLIENT.FOUND_ROWS
kwargs.update(settings_dict['DATABASE_OPTIONS']) kwargs.update(settings_dict['OPTIONS'])
self.connection = Database.connect(**kwargs) self.connection = Database.connect(**kwargs)
self.connection.encoders[SafeUnicode] = self.connection.encoders[unicode] self.connection.encoders[SafeUnicode] = self.connection.encoders[unicode]
self.connection.encoders[SafeString] = self.connection.encoders[str] self.connection.encoders[SafeString] = self.connection.encoders[str]

View File

@ -9,12 +9,12 @@ class DatabaseClient(BaseDatabaseClient):
def runshell(self): def runshell(self):
settings_dict = self.connection.settings_dict settings_dict = self.connection.settings_dict
args = [self.executable_name] args = [self.executable_name]
db = settings_dict['DATABASE_OPTIONS'].get('db', settings_dict['DATABASE_NAME']) db = settings_dict['OPTIONS'].get('db', settings_dict['NAME'])
user = settings_dict['DATABASE_OPTIONS'].get('user', settings_dict['DATABASE_USER']) user = settings_dict['OPTIONS'].get('user', settings_dict['USER'])
passwd = settings_dict['DATABASE_OPTIONS'].get('passwd', settings_dict['DATABASE_PASSWORD']) passwd = settings_dict['OPTIONS'].get('passwd', settings_dict['PASSWORD'])
host = settings_dict['DATABASE_OPTIONS'].get('host', settings_dict['DATABASE_HOST']) host = settings_dict['OPTIONS'].get('host', settings_dict['HOST'])
port = settings_dict['DATABASE_OPTIONS'].get('port', settings_dict['DATABASE_PORT']) port = settings_dict['OPTIONS'].get('port', settings_dict['PORT'])
defaults_file = settings_dict['DATABASE_OPTIONS'].get('read_default_file') defaults_file = settings_dict['OPTIONS'].get('read_default_file')
# Seems to be no good way to set sql_mode with CLI. # Seems to be no good way to set sql_mode with CLI.
if defaults_file: if defaults_file:

View File

@ -30,10 +30,10 @@ class DatabaseCreation(BaseDatabaseCreation):
def sql_table_creation_suffix(self): def sql_table_creation_suffix(self):
suffix = [] suffix = []
if self.connection.settings_dict['TEST_DATABASE_CHARSET']: if self.connection.settings_dict['TEST_CHARSET']:
suffix.append('CHARACTER SET %s' % self.connection.settings_dict['TEST_DATABASE_CHARSET']) suffix.append('CHARACTER SET %s' % self.connection.settings_dict['TEST_CHARSET'])
if self.connection.settings_dict['TEST_DATABASE_COLLATION']: if self.connection.settings_dict['TEST_COLLATION']:
suffix.append('COLLATE %s' % self.connection.settings_dict['TEST_DATABASE_COLLATION']) suffix.append('COLLATE %s' % self.connection.settings_dict['TEST_COLLATION'])
return ' '.join(suffix) return ' '.join(suffix)
def sql_for_inline_foreign_key_references(self, field, known_models, style): def sql_for_inline_foreign_key_references(self, field, known_models, style):

View File

@ -342,22 +342,22 @@ class DatabaseWrapper(BaseDatabaseWrapper):
def _connect_string(self): def _connect_string(self):
settings_dict = self.settings_dict settings_dict = self.settings_dict
if len(settings_dict['DATABASE_HOST'].strip()) == 0: if len(settings_dict['HOST'].strip()) == 0:
settings_dict['DATABASE_HOST'] = 'localhost' settings_dict['HOST'] = 'localhost'
if len(settings_dict['DATABASE_PORT'].strip()) != 0: if len(settings_dict['PORT'].strip()) != 0:
dsn = Database.makedsn(settings_dict['DATABASE_HOST'], dsn = Database.makedsn(settings_dict['HOST'],
int(settings_dict['DATABASE_PORT']), int(settings_dict['PORT']),
settings_dict['DATABASE_NAME']) settings_dict['NAME'])
else: else:
dsn = settings_dict['DATABASE_NAME'] dsn = settings_dict['NAME']
return "%s/%s@%s" % (settings_dict['DATABASE_USER'], return "%s/%s@%s" % (settings_dict['USER'],
settings_dict['DATABASE_PASSWORD'], dsn) settings_dict['PASSWORD'], dsn)
def _cursor(self): def _cursor(self):
cursor = None cursor = None
if not self._valid_connection(): if not self._valid_connection():
conn_string = convert_unicode(self._connect_string()) conn_string = convert_unicode(self._connect_string())
self.connection = Database.connect(conn_string, **self.settings_dict['DATABASE_OPTIONS']) self.connection = Database.connect(conn_string, **self.settings_dict['OPTIONS'])
cursor = FormatStylePlaceholderCursor(self.connection) cursor = FormatStylePlaceholderCursor(self.connection)
# Set oracle date to ansi date format. This only needs to execute # Set oracle date to ansi date format. This only needs to execute
# once when we create a new connection. We also set the Territory # once when we create a new connection. We also set the Territory

View File

@ -41,22 +41,22 @@ class DatabaseCreation(BaseDatabaseCreation):
remember = {} remember = {}
def _create_test_db(self, verbosity=1, autoclobber=False): def _create_test_db(self, verbosity=1, autoclobber=False):
TEST_DATABASE_NAME = self._test_database_name() TEST_NAME = self._test_database_name()
TEST_DATABASE_USER = self._test_database_user() TEST_USER = self._test_database_user()
TEST_DATABASE_PASSWD = self._test_database_passwd() TEST_PASSWD = self._test_database_passwd()
TEST_DATABASE_TBLSPACE = self._test_database_tblspace() TEST_TBLSPACE = self._test_database_tblspace()
TEST_DATABASE_TBLSPACE_TMP = self._test_database_tblspace_tmp() TEST_TBLSPACE_TMP = self._test_database_tblspace_tmp()
parameters = { parameters = {
'dbname': TEST_DATABASE_NAME, 'dbname': TEST_NAME,
'user': TEST_DATABASE_USER, 'user': TEST_USER,
'password': TEST_DATABASE_PASSWD, 'password': TEST_PASSWD,
'tblspace': TEST_DATABASE_TBLSPACE, 'tblspace': TEST_TBLSPACE,
'tblspace_temp': TEST_DATABASE_TBLSPACE_TMP, 'tblspace_temp': TEST_TBLSPACE_TMP,
} }
self.remember['user'] = self.connection.settings_dict['DATABASE_USER'] self.remember['user'] = self.connection.settings_dict['USER']
self.remember['passwd'] = self.connection.settings_dict['DATABASE_PASSWORD'] self.remember['passwd'] = self.connection.settings_dict['PASSWORD']
cursor = self.connection.cursor() cursor = self.connection.cursor()
if self._test_database_create(): if self._test_database_create():
@ -67,7 +67,7 @@ class DatabaseCreation(BaseDatabaseCreation):
except Exception, e: except Exception, e:
sys.stderr.write("Got an error creating the test database: %s\n" % e) sys.stderr.write("Got an error creating the test database: %s\n" % e)
if not autoclobber: if not autoclobber:
confirm = raw_input("It appears the test database, %s, already exists. Type 'yes' to delete it, or 'no' to cancel: " % TEST_DATABASE_NAME) confirm = raw_input("It appears the test database, %s, already exists. Type 'yes' to delete it, or 'no' to cancel: " % TEST_NAME)
if autoclobber or confirm == 'yes': if autoclobber or confirm == 'yes':
try: try:
if verbosity >= 1: if verbosity >= 1:
@ -91,7 +91,7 @@ class DatabaseCreation(BaseDatabaseCreation):
except Exception, e: except Exception, e:
sys.stderr.write("Got an error creating the test user: %s\n" % e) sys.stderr.write("Got an error creating the test user: %s\n" % e)
if not autoclobber: if not autoclobber:
confirm = raw_input("It appears the test user, %s, already exists. Type 'yes' to delete it, or 'no' to cancel: " % TEST_DATABASE_USER) confirm = raw_input("It appears the test user, %s, already exists. Type 'yes' to delete it, or 'no' to cancel: " % TEST_USER)
if autoclobber or confirm == 'yes': if autoclobber or confirm == 'yes':
try: try:
if verbosity >= 1: if verbosity >= 1:
@ -107,35 +107,35 @@ class DatabaseCreation(BaseDatabaseCreation):
print "Tests cancelled." print "Tests cancelled."
sys.exit(1) sys.exit(1)
self.connection.settings_dict['TEST_DATABASE_USER'] = self.connection.settings_dict["DATABASE_USER"] = TEST_DATABASE_USER self.connection.settings_dict['TEST_USER'] = self.connection.settings_dict["USER"] = TEST_USER
self.connection.settings_dict["DATABASE_PASSWORD"] = TEST_DATABASE_PASSWD self.connection.settings_dict["PASSWORD"] = TEST_PASSWD
return self.connection.settings_dict['DATABASE_NAME'] return self.connection.settings_dict['NAME']
def _destroy_test_db(self, test_database_name, verbosity=1): def _destroy_test_db(self, test_database_name, verbosity=1):
""" """
Destroy a test database, prompting the user for confirmation if the Destroy a test database, prompting the user for confirmation if the
database already exists. Returns the name of the test database created. database already exists. Returns the name of the test database created.
""" """
TEST_DATABASE_NAME = self._test_database_name() TEST_NAME = self._test_database_name()
TEST_DATABASE_USER = self._test_database_user() TEST_USER = self._test_database_user()
TEST_DATABASE_PASSWD = self._test_database_passwd() TEST_PASSWD = self._test_database_passwd()
TEST_DATABASE_TBLSPACE = self._test_database_tblspace() TEST_TBLSPACE = self._test_database_tblspace()
TEST_DATABASE_TBLSPACE_TMP = self._test_database_tblspace_tmp() TEST_TBLSPACE_TMP = self._test_database_tblspace_tmp()
self.connection.settings_dict["DATABASE_USER"] = self.remember['user'] self.connection.settings_dict["USER"] = self.remember['user']
self.connection.settings_dict["DATABASE_PASSWORD"] = self.remember['passwd'] self.connection.settings_dict["PASSWORD"] = self.remember['passwd']
parameters = { parameters = {
'dbname': TEST_DATABASE_NAME, 'dbname': TEST_NAME,
'user': TEST_DATABASE_USER, 'user': TEST_USER,
'password': TEST_DATABASE_PASSWD, 'password': TEST_PASSWD,
'tblspace': TEST_DATABASE_TBLSPACE, 'tblspace': TEST_TBLSPACE,
'tblspace_temp': TEST_DATABASE_TBLSPACE_TMP, 'tblspace_temp': TEST_TBLSPACE_TMP,
} }
self.remember['user'] = self.connection.settings_dict['DATABASE_USER'] self.remember['user'] = self.connection.settings_dict['USER']
self.remember['passwd'] = self.connection.settings_dict['DATABASE_PASSWORD'] self.remember['passwd'] = self.connection.settings_dict['PASSWORD']
cursor = self.connection.cursor() cursor = self.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.
@ -207,10 +207,10 @@ class DatabaseCreation(BaseDatabaseCreation):
raise raise
def _test_database_name(self): def _test_database_name(self):
name = TEST_DATABASE_PREFIX + self.connection.settings_dict['DATABASE_NAME'] name = TEST_DATABASE_PREFIX + self.connection.settings_dict['NAME']
try: try:
if self.connection.settings_dict['TEST_DATABASE_NAME']: if self.connection.settings_dict['TEST_NAME']:
name = self.connection.settings_dict['TEST_DATABASE_NAME'] name = self.connection.settings_dict['TEST_NAME']
except AttributeError: except AttributeError:
pass pass
except: except:
@ -220,7 +220,7 @@ class DatabaseCreation(BaseDatabaseCreation):
def _test_database_create(self): def _test_database_create(self):
name = True name = True
try: try:
if self.connection.settings_dict['TEST_DATABASE_CREATE']: if self.connection.settings_dict['TEST_CREATE']:
name = True name = True
else: else:
name = False name = False
@ -244,10 +244,10 @@ class DatabaseCreation(BaseDatabaseCreation):
return name return name
def _test_database_user(self): def _test_database_user(self):
name = TEST_DATABASE_PREFIX + self.connection.settings_dict['DATABASE_USER'] name = TEST_DATABASE_PREFIX + self.connection.settings_dict['USER']
try: try:
if self.connection.settings_dict['TEST_DATABASE_USER']: if self.connection.settings_dict['TEST_USER']:
name = self.connection.settings_dict['TEST_DATABASE_USER'] name = self.connection.settings_dict['TEST_USER']
except KeyError: except KeyError:
pass pass
except: except:
@ -257,8 +257,8 @@ class DatabaseCreation(BaseDatabaseCreation):
def _test_database_passwd(self): def _test_database_passwd(self):
name = PASSWORD name = PASSWORD
try: try:
if self.connection.settings_dict['TEST_DATABASE_PASSWD']: if self.connection.settings_dict['TEST_PASSWD']:
name = self.connection.settings_dict['TEST_DATABASE_PASSWD'] name = self.connection.settings_dict['TEST_PASSWD']
except KeyError: except KeyError:
pass pass
except: except:
@ -266,10 +266,10 @@ class DatabaseCreation(BaseDatabaseCreation):
return name return name
def _test_database_tblspace(self): def _test_database_tblspace(self):
name = TEST_DATABASE_PREFIX + self.connection.settings_dict['DATABASE_NAME'] name = TEST_DATABASE_PREFIX + self.connection.settings_dict['NAME']
try: try:
if self.connection.settings_dict['TEST_DATABASE_TBLSPACE']: if self.connection.settings_dict['TEST_TBLSPACE']:
name = self.connection.settings_dict['TEST_DATABASE_TBLSPACE'] name = self.connection.settings_dict['TEST_TBLSPACE']
except KeyError: except KeyError:
pass pass
except: except:
@ -277,10 +277,10 @@ class DatabaseCreation(BaseDatabaseCreation):
return name return name
def _test_database_tblspace_tmp(self): def _test_database_tblspace_tmp(self):
name = TEST_DATABASE_PREFIX + self.connection.settings_dict['DATABASE_NAME'] + '_temp' name = TEST_DATABASE_PREFIX + self.connection.settings_dict['NAME'] + '_temp'
try: try:
if self.connection.settings_dict['TEST_DATABASE_TBLSPACE_TMP']: if self.connection.settings_dict['TEST_TBLSPACE_TMP']:
name = self.connection.settings_dict['TEST_DATABASE_TBLSPACE_TMP'] name = self.connection.settings_dict['TEST_TBLSPACE_TMP']
except KeyError: except KeyError:
pass pass
except: except:

View File

@ -101,19 +101,19 @@ class DatabaseWrapper(BaseDatabaseWrapper):
settings_dict = self.settings_dict settings_dict = self.settings_dict
if self.connection is None: if self.connection is None:
set_tz = True set_tz = True
if settings_dict['DATABASE_NAME'] == '': if settings_dict['NAME'] == '':
from django.core.exceptions import ImproperlyConfigured from django.core.exceptions import ImproperlyConfigured
raise ImproperlyConfigured("You need to specify DATABASE_NAME in your Django settings file.") raise ImproperlyConfigured("You need to specify NAME in your Django settings file.")
conn_string = "dbname=%s" % settings_dict['DATABASE_NAME'] conn_string = "dbname=%s" % settings_dict['NAME']
if settings_dict['DATABASE_USER']: if settings_dict['USER']:
conn_string = "user=%s %s" % (settings_dict['DATABASE_USER'], conn_string) conn_string = "user=%s %s" % (settings_dict['USER'], conn_string)
if settings_dict['DATABASE_PASSWORD']: if settings_dict['PASSWORD']:
conn_string += " password='%s'" % settings_dict['DATABASE_PASSWORD'] conn_string += " password='%s'" % settings_dict['PASSWORD']
if settings_dict['DATABASE_HOST']: if settings_dict['HOST']:
conn_string += " host=%s" % settings_dict['DATABASE_HOST'] conn_string += " host=%s" % settings_dict['HOST']
if settings_dict['DATABASE_PORT']: if settings_dict['PORT']:
conn_string += " port=%s" % settings_dict['DATABASE_PORT'] conn_string += " port=%s" % settings_dict['PORT']
self.connection = Database.connect(conn_string, **settings_dict['DATABASE_OPTIONS']) self.connection = Database.connect(conn_string, **settings_dict['OPTIONS'])
self.connection.set_isolation_level(1) # make transactions transparent to all cursors self.connection.set_isolation_level(1) # make transactions transparent to all cursors
connection_created.send(sender=self.__class__) connection_created.send(sender=self.__class__)
cursor = self.connection.cursor() cursor = self.connection.cursor()
@ -142,7 +142,7 @@ def typecast_string(s):
try: try:
Database.register_type(Database.new_type((1082,), "DATE", util.typecast_date)) Database.register_type(Database.new_type((1082,), "DATE", util.typecast_date))
except AttributeError: except AttributeError:
raise Exception("You appear to be using psycopg version 2. Set your DATABASE_ENGINE to 'postgresql_psycopg2' instead of 'postgresql'.") raise Exception("You appear to be using psycopg version 2. Set your DATABASES.ENGINE to 'postgresql_psycopg2' instead of 'postgresql'.")
Database.register_type(Database.new_type((1083,1266), "TIME", util.typecast_time)) Database.register_type(Database.new_type((1083,1266), "TIME", util.typecast_time))
Database.register_type(Database.new_type((1114,1184), "TIMESTAMP", util.typecast_timestamp)) Database.register_type(Database.new_type((1114,1184), "TIMESTAMP", util.typecast_timestamp))
Database.register_type(Database.new_type((16,), "BOOLEAN", util.typecast_boolean)) Database.register_type(Database.new_type((16,), "BOOLEAN", util.typecast_boolean))

View File

@ -9,13 +9,13 @@ class DatabaseClient(BaseDatabaseClient):
def runshell(self): def runshell(self):
settings_dict = self.connection.settings_dict settings_dict = self.connection.settings_dict
args = [self.executable_name] args = [self.executable_name]
if settings_dict['DATABASE_USER']: if settings_dict['USER']:
args += ["-U", settings_dict['DATABASE_USER']] args += ["-U", settings_dict['USER']]
if settings_dict['DATABASE_HOST']: if settings_dict['HOST']:
args.extend(["-h", settings_dict['DATABASE_HOST']]) args.extend(["-h", settings_dict['HOST']])
if settings_dict['DATABASE_PORT']: if settings_dict['PORT']:
args.extend(["-p", str(settings_dict['DATABASE_PORT'])]) args.extend(["-p", str(settings_dict['PORT'])])
args += [settings_dict['DATABASE_NAME']] args += [settings_dict['NAME']]
if os.name == 'nt': if os.name == 'nt':
sys.exit(os.system(" ".join(args))) sys.exit(os.system(" ".join(args)))
else: else:

View File

@ -29,7 +29,7 @@ class DatabaseCreation(BaseDatabaseCreation):
} }
def sql_table_creation_suffix(self): def sql_table_creation_suffix(self):
assert self.connection.settings_dict['TEST_DATABASE_COLLATION'] is None, "PostgreSQL does not support collation setting at database creation time." assert self.connection.settings_dict['TEST_COLLATION'] is None, "PostgreSQL does not support collation setting at database creation time."
if self.connection.settings_dict['TEST_DATABASE_CHARSET']: if self.connection.settings_dict['TEST_CHARSET']:
return "WITH ENCODING '%s'" % self.connection.settings_dict['TEST_DATABASE_CHARSET'] return "WITH ENCODING '%s'" % self.connection.settings_dict['TEST_CHARSET']
return '' return ''

View File

@ -63,7 +63,7 @@ class DatabaseWrapper(BaseDatabaseWrapper):
super(DatabaseWrapper, self).__init__(*args, **kwargs) super(DatabaseWrapper, self).__init__(*args, **kwargs)
self.features = DatabaseFeatures() self.features = DatabaseFeatures()
autocommit = self.settings_dict["DATABASE_OPTIONS"].get('autocommit', False) autocommit = self.settings_dict["OPTIONS"].get('autocommit', False)
self.features.uses_autocommit = autocommit self.features.uses_autocommit = autocommit
self._set_isolation_level(int(not autocommit)) self._set_isolation_level(int(not autocommit))
self.ops = DatabaseOperations(self) self.ops = DatabaseOperations(self)
@ -77,23 +77,23 @@ class DatabaseWrapper(BaseDatabaseWrapper):
settings_dict = self.settings_dict settings_dict = self.settings_dict
if self.connection is None: if self.connection is None:
set_tz = True set_tz = True
if settings_dict['DATABASE_NAME'] == '': if settings_dict['NAME'] == '':
from django.core.exceptions import ImproperlyConfigured from django.core.exceptions import ImproperlyConfigured
raise ImproperlyConfigured("You need to specify DATABASE_NAME in your Django settings file.") raise ImproperlyConfigured("You need to specify NAME in your Django settings file.")
conn_params = { conn_params = {
'database': settings_dict['DATABASE_NAME'], 'database': settings_dict['NAME'],
} }
conn_params.update(settings_dict['DATABASE_OPTIONS']) conn_params.update(settings_dict['OPTIONS'])
if 'autocommit' in conn_params: if 'autocommit' in conn_params:
del conn_params['autocommit'] del conn_params['autocommit']
if settings_dict['DATABASE_USER']: if settings_dict['USER']:
conn_params['user'] = settings_dict['DATABASE_USER'] conn_params['user'] = settings_dict['USER']
if settings_dict['DATABASE_PASSWORD']: if settings_dict['PASSWORD']:
conn_params['password'] = settings_dict['DATABASE_PASSWORD'] conn_params['password'] = settings_dict['PASSWORD']
if settings_dict['DATABASE_HOST']: if settings_dict['HOST']:
conn_params['host'] = settings_dict['DATABASE_HOST'] conn_params['host'] = settings_dict['HOST']
if settings_dict['DATABASE_PORT']: if settings_dict['PORT']:
conn_params['port'] = settings_dict['DATABASE_PORT'] conn_params['port'] = settings_dict['PORT']
self.connection = Database.connect(**conn_params) self.connection = Database.connect(**conn_params)
self.connection.set_client_encoding('UTF8') self.connection.set_client_encoding('UTF8')
self.connection.set_isolation_level(self.isolation_level) self.connection.set_isolation_level(self.isolation_level)

View File

@ -159,14 +159,14 @@ class DatabaseWrapper(BaseDatabaseWrapper):
def _cursor(self): def _cursor(self):
if self.connection is None: if self.connection is None:
settings_dict = self.settings_dict settings_dict = self.settings_dict
if not settings_dict['DATABASE_NAME']: if not settings_dict['NAME']:
from django.core.exceptions import ImproperlyConfigured from django.core.exceptions import ImproperlyConfigured
raise ImproperlyConfigured, "Please fill out DATABASE_NAME in the settings module before using the database." raise ImproperlyConfigured, "Please fill out the database NAME in the settings module before using the database."
kwargs = { kwargs = {
'database': settings_dict['DATABASE_NAME'], 'database': settings_dict['NAME'],
'detect_types': Database.PARSE_DECLTYPES | Database.PARSE_COLNAMES, 'detect_types': Database.PARSE_DECLTYPES | Database.PARSE_COLNAMES,
} }
kwargs.update(settings_dict['DATABASE_OPTIONS']) kwargs.update(settings_dict['OPTIONS'])
self.connection = Database.connect(**kwargs) self.connection = Database.connect(**kwargs)
# Register extract, date_trunc, and regexp functions. # Register extract, date_trunc, and regexp functions.
self.connection.create_function("django_extract", 2, _sqlite_extract) self.connection.create_function("django_extract", 2, _sqlite_extract)
@ -179,7 +179,7 @@ class DatabaseWrapper(BaseDatabaseWrapper):
# If database is in memory, closing the connection destroys the # If database is in memory, closing the connection destroys the
# database. To prevent accidental data loss, ignore close requests on # database. To prevent accidental data loss, ignore close requests on
# an in-memory db. # an in-memory db.
if self.settings_dict['DATABASE_NAME'] != ":memory:": if self.settings_dict['NAME'] != ":memory:":
BaseDatabaseWrapper.close(self) BaseDatabaseWrapper.close(self)
class SQLiteCursorWrapper(Database.Cursor): class SQLiteCursorWrapper(Database.Cursor):

View File

@ -8,7 +8,7 @@ class DatabaseClient(BaseDatabaseClient):
def runshell(self): def runshell(self):
args = [self.executable_name, args = [self.executable_name,
self.connection.settings_dict['DATABASE_NAME']] self.connection.settings_dict['NAME']]
if os.name == 'nt': if os.name == 'nt':
sys.exit(os.system(" ".join(args))) sys.exit(os.system(" ".join(args)))
else: else:

View File

@ -38,7 +38,7 @@ class DatabaseCreation(BaseDatabaseCreation):
return [] return []
def _create_test_db(self, verbosity, autoclobber): def _create_test_db(self, verbosity, autoclobber):
test_database_name = self.connection.settings_dict['TEST_DATABASE_NAME'] test_database_name = self.connection.settings_dict['TEST_NAME']
if test_database_name and test_database_name != ":memory:": if test_database_name and test_database_name != ":memory:":
# Erase the old test database # Erase the old test database
if verbosity >= 1: if verbosity >= 1:

View File

@ -6,13 +6,15 @@ from django.utils.importlib import import_module
def load_backend(backend_name): def load_backend(backend_name):
try: try:
# Most of the time, the database backend will be one of the official module = import_module('.base', 'django.db.backends.%s' % backend_name)
# backends that ships with Django, so look there first. import warnings
return import_module('.base', 'django.db.backends.%s' % backend_name) warnings.warn(
"Short names for DATABASE_ENGINE are deprecated; prepend with 'django.db.backends.'",
PendingDeprecationWarning
)
return module
except ImportError, e: except ImportError, e:
raise # Look for a fully qualified database backend name
# If the import failed, we might be looking for a database backend
# distributed external to Django. So we'll try that next.
try: try:
return import_module('.base', backend_name) return import_module('.base', backend_name)
except ImportError, e_user: except ImportError, e_user:
@ -50,14 +52,13 @@ class ConnectionHandler(object):
conn = self.databases[alias] conn = self.databases[alias]
except KeyError: except KeyError:
raise ConnectionDoesNotExist("The connection %s doesn't exist" % alias) raise ConnectionDoesNotExist("The connection %s doesn't exist" % alias)
conn.setdefault('DATABASE_ENGINE', 'dummy') conn.setdefault('ENGINE', 'dummy')
conn.setdefault('DATABASE_OPTIONS', {}) conn.setdefault('OPTIONS', {})
conn.setdefault('TEST_DATABASE_CHARSET', None) conn.setdefault('TEST_CHARSET', None)
conn.setdefault('TEST_DATABASE_COLLATION', None) conn.setdefault('TEST_COLLATION', None)
conn.setdefault('TEST_DATABASE_NAME', None) conn.setdefault('TEST_NAME', None)
conn.setdefault('TIME_ZONE', settings.TIME_ZONE) conn.setdefault('TIME_ZONE', settings.TIME_ZONE)
for setting in ('DATABASE_NAME', 'DATABASE_USER', 'DATABASE_PASSWORD', for setting in ('NAME', 'USER', 'PASSWORD', 'HOST', 'PORT'):
'DATABASE_HOST', 'DATABASE_PORT'):
conn.setdefault(setting, '') conn.setdefault(setting, '')
def __getitem__(self, alias): def __getitem__(self, alias):
@ -66,7 +67,7 @@ class ConnectionHandler(object):
self.ensure_defaults(alias) self.ensure_defaults(alias)
db = self.databases[alias] db = self.databases[alias]
backend = load_backend(db['DATABASE_ENGINE']) backend = load_backend(db['ENGINE'])
conn = backend.DatabaseWrapper(db, alias) conn = backend.DatabaseWrapper(db, alias)
self._connections[alias] = conn self._connections[alias] = conn
return conn return conn

View File

@ -190,7 +190,7 @@ def run_tests(test_labels, verbosity=1, interactive=True, extra_tests=[]):
from django.db import connections from django.db import connections
for alias in connections: for alias in connections:
connection = connections[alias] connection = connections[alias]
old_names.append((connection, connection.settings_dict['DATABASE_NAME'])) old_names.append((connection, connection.settings_dict['NAME']))
connection.creation.create_test_db(verbosity, autoclobber=not interactive) connection.creation.create_test_db(verbosity, autoclobber=not interactive)
result = unittest.TextTestRunner(verbosity=verbosity).run(suite) result = unittest.TextTestRunner(verbosity=verbosity).run(suite)
for connection, old_name in old_names: for connection, old_name in old_names:

View File

@ -446,7 +446,7 @@ def connections_support_transactions():
Returns True if all connections support transactions. This is messy Returns True if all connections support transactions. This is messy
because 2.4 doesn't support any or all. because 2.4 doesn't support any or all.
""" """
return all(conn.settings_dict['DATABASE_SUPPORTS_TRANSACTIONS'] return all(conn.settings_dict['SUPPORTS_TRANSACTIONS']
for conn in connections.all()) for conn in connections.all())
class TestCase(TransactionTestCase): class TestCase(TransactionTestCase):

View File

@ -809,7 +809,7 @@ EMPTY_URLCONF_TEMPLATE = """
<div id="instructions"> <div id="instructions">
<p>Of course, you haven't actually done any work yet. Here's what to do next:</p> <p>Of course, you haven't actually done any work yet. Here's what to do next:</p>
<ul> <ul>
<li>If you plan to use a database, edit the <code>DATABASE_*</code> settings in <code>{{ project_name }}/settings.py</code>.</li> <li>If you plan to use a database, edit the <code>DATABASES</code> setting in <code>{{ project_name }}/settings.py</code>.</li>
<li>Start your first app by running <code>python {{ project_name }}/manage.py startapp [appname]</code>.</li> <li>Start your first app by running <code>python {{ project_name }}/manage.py startapp [appname]</code>.</li>
</ul> </ul>
</div> </div>

View File

@ -290,13 +290,13 @@ If you aim to build a database-agnostic application, you should account for
differences in database column types. For example, the date/time column type differences in database column types. For example, the date/time column type
in PostgreSQL is called ``timestamp``, while the same column in MySQL is called in PostgreSQL is called ``timestamp``, while the same column in MySQL is called
``datetime``. The simplest way to handle this in a ``db_type()`` method is to ``datetime``. The simplest way to handle this in a ``db_type()`` method is to
check the ``connection.settings_dict['DATABASE_ENGINE']`` attribute. check the ``connection.settings_dict['ENGINE']`` attribute.
For example:: For example::
class MyDateField(models.Field): class MyDateField(models.Field):
def db_type(self, connection): def db_type(self, connection):
if connection.settings_dict['DATABASE_ENGINE'] == 'mysql': if connection.settings_dict['ENGINE'] == 'django.db.backends.mysql':
return 'datetime' return 'datetime'
else: else:
return 'timestamp' return 'timestamp'

View File

@ -118,23 +118,27 @@ The SQL files are read by the :djadmin:`sqlcustom`, :djadmin:`sqlreset`,
<ref-django-admin>`. Refer to the :ref:`manage.py documentation <ref-django-admin>`. Refer to the :ref:`manage.py documentation
<ref-django-admin>` for more information. <ref-django-admin>` for more information.
Note that if you have multiple SQL data files, there's no guarantee of the order Note that if you have multiple SQL data files, there's no guarantee of
in which they're executed. The only thing you can assume is that, by the time the order in which they're executed. The only thing you can assume is
your custom data files are executed, all the database tables already will have that, by the time your custom data files are executed, all the
been created. database tables already will have been created.
Database-backend-specific SQL data Database-backend-specific SQL data
---------------------------------- ----------------------------------
There's also a hook for backend-specific SQL data. For example, you can have There's also a hook for backend-specific SQL data. For example, you
separate initial-data files for PostgreSQL and MySQL. For each app, Django can have separate initial-data files for PostgreSQL and MySQL. For
looks for a file called ``<appname>/sql/<modelname>.<backend>.sql``, where each app, Django looks for a file called
``<appname>`` is your app directory, ``<modelname>`` is the model's name in ``<appname>/sql/<modelname>.<backend>.sql``, where ``<appname>`` is
lowercase and ``<backend>`` is the value of ``DATABASE_ENGINE`` for the given your app directory, ``<modelname>`` is the model's name in lowercase
database being set up in your settings file (e.g., ``postgresql``, ``mysql``). and ``<backend>`` is the last part of the module name provided for the
:setting:`ENGINE` in your settings file (e.g., if you have defined a
database with an :setting:`ENGINE` value of
``django.db.backends.postgresql``, Django will look for
``<appname>/sql/<modelname>.postgresql.sql``).
Backend-specific SQL data is executed before non-backend-specific SQL data. For Backend-specific SQL data is executed before non-backend-specific SQL
example, if your app contains the files ``sql/person.sql`` and data. For example, if your app contains the files ``sql/person.sql``
``sql/person.postgresql.sql`` and you're installing the app on PostgreSQL, and ``sql/person.postgresql.sql`` and you're installing the app on
Django will execute the contents of ``sql/person.postgresql.sql`` first, then PostgreSQL, Django will execute the contents of
``sql/person.sql``. ``sql/person.postgresql.sql`` first, then ``sql/person.sql``.

View File

@ -19,15 +19,15 @@ Give Django your database parameters
You'll need to tell Django what your database connection parameters are, and You'll need to tell Django what your database connection parameters are, and
what the name of the database is. Do that by editing the :setting:`DATABASES` what the name of the database is. Do that by editing the :setting:`DATABASES`
setting and assigning values to the following keys in the ``'default'`` setting and assigning values to the following keys for the ``'default'``
dictionary: connection:
* ``DATABASE_NAME`` * :setting:`NAME`
* ``DATABASE_ENGINE`` * :setting:`ENGINE`
* ``DATABASE_USER`` * :setting:`USER`
* ``DATABASE_PASSWORD`` * :setting:`PASSWORD`
* ``DATABASE_HOST`` * :setting:`HOST`
* ``DATABASE_PORT`` * :setting:`PORT`
Auto-generate the models Auto-generate the models
======================== ========================

View File

@ -763,18 +763,18 @@ info. Your :setting:`DATABASES` setting needs to define two databases:
want. It doesn't need to use the same backend as the ``default`` want. It doesn't need to use the same backend as the ``default``
database (although it can use the same backend if you want to). database (although it can use the same backend if you want to).
If you're using the ``sqlite3`` database backend, you need to define If you're using the SQLite database backend, you need to define
:setting:`DATABASE_ENGINE` for both databases, plus a :setting:`ENGINE` for both databases, plus a
:setting:`TEST_DATABASE_NAME` for the ``other`` database. The :setting:`TEST_NAME` for the ``other`` database. The
following is a minimal settings file that can be used to test SQLite:: following is a minimal settings file that can be used to test SQLite::
DATABASES = { DATABASES = {
'default': { 'default': {
'DATABASE_ENGINE': 'sqlite3' 'ENGINE': 'django.db.backends.sqlite3'
}, },
'other': { 'other': {
'DATABASE_ENGINE': 'sqlite3', 'ENGINE': 'django.db.backends.sqlite3',
'TEST_DATABASE_NAME: 'other_db' 'TEST_NAME: 'other_db'
} }
} }
@ -782,22 +782,22 @@ following is a minimal settings file that can be used to test SQLite::
If you're using another backend, you will need to provide other details for If you're using another backend, you will need to provide other details for
each database: each database:
* The :setting:`DATABASE_USER` option for each of your databases needs to * The :setting:`USER` option for each of your databases needs to
specify an existing user account for the database. specify an existing user account for the database.
* The :setting:`DATABASE_PASSWORD` option needs to provide the password for * The :setting:`PASSWORD` option needs to provide the password for
the :setting:`DATABASE_USER` that has been specified. the :setting:`USER` that has been specified.
* The :setting:`DATABASE_NAME` option must be the name of an existing database to * The :setting:`NAME` option must be the name of an existing database to
which the given user has permission to connect. The unit tests will not which the given user has permission to connect. The unit tests will not
touch this database; the test runner creates a new database whose name is touch this database; the test runner creates a new database whose name is
:setting:`DATABASE_NAME` prefixed with ``test_``, and this test database is :setting:`NAME` prefixed with ``test_``, and this test database is
deleted when the tests are finished. This means your user account needs deleted when the tests are finished. This means your user account needs
permission to execute ``CREATE DATABASE``. permission to execute ``CREATE DATABASE``.
You will also need to ensure that your database uses UTF-8 as the default You will also need to ensure that your database uses UTF-8 as the default
character set. If your database server doesn't use UTF-8 as a default charset, character set. If your database server doesn't use UTF-8 as a default charset,
you will need to include a value for ``TEST_DATABASE_CHARSET`` in the settings you will need to include a value for ``TEST_CHARSET`` in the settings
dictionary for the applicable database. dictionary for the applicable database.
If you want to run the full suite of tests, you'll need to install a number of If you want to run the full suite of tests, you'll need to install a number of

View File

@ -158,35 +158,40 @@ It worked!
Database setup Database setup
-------------- --------------
Now, edit :file:`settings.py`. It's a normal Python module with module-level Now, edit :file:`settings.py`. It's a normal Python module with
variables representing Django settings. Change the following keys in the module-level variables representing Django settings. Change the
:setting:`DATABASES` ``'default'`` item to match your databases connection following keys in the :setting:`DATABASES` ``'default'`` item to match
settings. your databases connection settings.
* ``DATABASE_ENGINE`` -- Either 'postgresql_psycopg2', 'mysql' or * :setting:`ENGINE` -- Either
'sqlite3'. Other backends are :setting:`also available <DATABASE_ENGINE>`. ``'django.db.backends.postgresql_psycopg2'``,
``'django.db.backends.mysql'`` or
``'django.db.backends.sqlite3'``. Other backends are
:setting:`also available <ENGINE>`.
* ``DATABASE_NAME`` -- The name of your database. If you're using * :setting:`NAME` -- The name of your database. If you're using
SQLite, the database will be a file on your computer; in that case, SQLite, the database will be a file on your computer; in that
``DATABASE_NAME`` should be the full absolute path, including filename, of case, :setting:`NAME` should be the full absolute path,
that file. If the file doesn't exist, it will automatically be created including filename, of that file. If the file doesn't exist, it
when you synchronize the database for the first time (see below). will automatically be created when you synchronize the database
for the first time (see below).
When specifying the path, always use forward slashes, even on Windows When specifying the path, always use forward slashes, even on
(e.g. ``C:/homes/user/mysite/sqlite3.db``). Windows (e.g. ``C:/homes/user/mysite/sqlite3.db``).
* ``DATABASE_USER`` -- Your database username (not used for SQLite). * :setting:`USER` -- Your database username (not used for SQLite).
* ``DATABASE_PASSWORD`` -- Your database password (not used for * :setting:`PASSWORD` -- Your database password (not used for
SQLite). SQLite).
* ``DATABASE_HOST`` -- The host your database is on. Leave this as an * :setting:`HOST` -- The host your database is on. Leave this as
empty string if your database server is on the same physical machine (not an empty string if your database server is on the same physical
used for SQLite). machine (not used for SQLite).
If you're new to databases, we recommend simply using SQLite (by setting If you're new to databases, we recommend simply using SQLite (by
``DATABASE_ENGINE`` to ``'sqlite3'``). SQLite is included as part of setting :setting:`ENGINE` to ``'django.db.backends.sqlite3'``). SQLite
Python 2.5 and later, so you won't need to install anything else. is included as part of Python 2.5 and later, so you won't need to
install anything else.
.. note:: .. note::

View File

@ -28,8 +28,8 @@ Compiles .po files to .mo files for use with builtin gettext support.
Creates the table needed to use the SQL cache backend Creates the table needed to use the SQL cache backend
.TP .TP
.B dbshell .B dbshell
Runs the command\-line client for the current Runs the command\-line client for the specified
.BI DATABASE_ENGINE. .BI database ENGINE.
.TP .TP
.B diffsettings .B diffsettings
Displays differences between the current Displays differences between the current

View File

@ -44,18 +44,20 @@ Autocommit mode
.. versionadded:: 1.1 .. versionadded:: 1.1
If your application is particularly read-heavy and doesn't make many database If your application is particularly read-heavy and doesn't make many
writes, the overhead of a constantly open transaction can sometimes be database writes, the overhead of a constantly open transaction can
noticeable. For those situations, if you're using the ``postgresql_psycopg2`` sometimes be noticeable. For those situations, if you're using the
backend, you can configure Django to use *"autocommit"* behavior for the ``postgresql_psycopg2`` backend, you can configure Django to use
connection, meaning that each database operation will normally be in its own *"autocommit"* behavior for the connection, meaning that each database
transaction, rather than having the transaction extend over multiple operation will normally be in its own transaction, rather than having
operations. In this case, you can still manually start a transaction if you're the transaction extend over multiple operations. In this case, you can
doing something that requires consistency across multiple database operations. still manually start a transaction if you're doing something that
The autocommit behavior is enabled by setting the ``autocommit`` key in the requires consistency across multiple database operations. The
``DATABASE_OPTIONS`` part of your database in :setting:`DATABASES`:: autocommit behavior is enabled by setting the ``autocommit`` key in
the :setting:`OPTIONS` part of your database configuration in
:setting:`DATABASES`::
DATABASE_OPTIONS = { OPTIONS = {
"autocommit": True, "autocommit": True,
} }
@ -67,11 +69,11 @@ objects are changed or none of them are.
.. admonition:: This is database-level autocommit .. admonition:: This is database-level autocommit
This functionality is not the same as the This functionality is not the same as the
:ref:`topics-db-transactions-autocommit` decorator. That decorator is a :ref:`topics-db-transactions-autocommit` decorator. That decorator
Django-level implementation that commits automatically after data changing is a Django-level implementation that commits automatically after
operations. The feature enabled using the ``DATABASE_OPTIONS`` option data changing operations. The feature enabled using the
provides autocommit behavior at the database adapter level. It commits :setting:`OPTIONS` option provides autocommit behavior at the
after *every* operation. database adapter level. It commits after *every* operation.
If you are using this feature and performing an operation akin to delete or If you are using this feature and performing an operation akin to delete or
updating that requires multiple operations, you are strongly recommended to updating that requires multiple operations, you are strongly recommended to
@ -234,14 +236,13 @@ Refer to the :ref:`settings documentation <ref-settings>`.
Connection settings are used in this order: Connection settings are used in this order:
1. ``DATABASE_OPTIONS``. 1. :setting:`OPTIONS`.
2. ``DATABASE_NAME``, ``DATABASE_USER``, 2. :setting:`NAME`, :setting:`USER`, :setting:`PASSWORD`,
``DATABASE_PASSWORD``, ``DATABASE_HOST``, :setting:`HOST`, :setting:`PORT`
``DATABASE_PORT``
3. MySQL option files. 3. MySQL option files.
In other words, if you set the name of the database in ``DATABASE_OPTIONS``, In other words, if you set the name of the database in ``OPTIONS``,
this will take precedence over ``DATABASE_NAME``, which would override this will take precedence over ``NAME``, which would override
anything in a `MySQL option file`_. anything in a `MySQL option file`_.
Here's a sample configuration which uses a MySQL option file:: Here's a sample configuration which uses a MySQL option file::
@ -249,8 +250,8 @@ Here's a sample configuration which uses a MySQL option file::
# settings.py # settings.py
DATABASES = { DATABASES = {
'default': { 'default': {
'DATABASE_ENGINE': "mysql", 'ENGINE': 'django.db.backends.mysql',
'DATABASE_OPTIONS': { 'OPTIONS': {
'read_default_file': '/path/to/my.cnf', 'read_default_file': '/path/to/my.cnf',
}, },
} }
@ -258,9 +259,9 @@ Here's a sample configuration which uses a MySQL option file::
# my.cnf # my.cnf
[client] [client]
database = DATABASE_NAME database = NAME
user = DATABASE_USER user = USER
password = DATABASE_PASSWORD password = PASSWORD
default-character-set = utf8 default-character-set = utf8
Several other MySQLdb connection options may be useful, such as ``ssl``, Several other MySQLdb connection options may be useful, such as ``ssl``,
@ -291,7 +292,7 @@ storage engine, you have a couple of options.
* Another option is to use the ``init_command`` option for MySQLdb prior to * Another option is to use the ``init_command`` option for MySQLdb prior to
creating your tables:: creating your tables::
DATABASE_OPTIONS = { OPTIONS = {
"init_command": "SET storage_engine=INNODB", "init_command": "SET storage_engine=INNODB",
} }
@ -456,7 +457,7 @@ If you're getting this error, you can solve it by:
* Increase the default timeout value by setting the ``timeout`` database * Increase the default timeout value by setting the ``timeout`` database
option option:: option option::
DATABASE_OPTIONS = { OPTIONS = {
# ... # ...
"timeout": 20, "timeout": 20,
# ... # ...
@ -511,32 +512,32 @@ Your Django settings.py file should look something like this for Oracle::
DATABASES = { DATABASES = {
'default': { 'default': {
'DATABASE_ENGINE': 'oracle', 'ENGINE': 'django.db.backends.oracle',
'DATABASE_NAME': 'xe', 'NAME': 'xe',
'DATABASE_USER': 'a_user', 'USER': 'a_user',
'DATABASE_PASSWORD': 'a_password', 'PASSWORD': 'a_password',
'DATABASE_HOST': '', 'HOST': '',
'DATABASE_PORT': '' , 'PORT': '' ,
} }
} }
If you don't use a ``tnsnames.ora`` file or a similar naming method that If you don't use a ``tnsnames.ora`` file or a similar naming method that
recognizes the SID ("xe" in this example), then fill in both recognizes the SID ("xe" in this example), then fill in both
``DATABASE_HOST`` and ``DATABASE_PORT`` like so:: ``HOST`` and ``PORT`` like so::
DATABASES = { DATABASES = {
'default': { 'default': {
'DATABASE_ENGINE': 'oracle', 'ENGINE': 'django.db.backends.oracle',
'DATABASE_NAME': 'xe', 'NAME': 'xe',
'DATABASE_USER': 'a_user', 'USER': 'a_user',
'DATABASE_PASSWORD': 'a_password', 'PASSWORD': 'a_password',
'DATABASE_HOST': 'dbprod01ned.mycompany.com', 'HOST': 'dbprod01ned.mycompany.com',
'DATABASE_PORT': '1540', 'PORT': '1540',
} }
} }
You should supply both ``DATABASE_HOST`` and ``DATABASE_PORT``, or leave both You should supply both ``HOST`` and ``PORT``, or leave both
as empty strings. as empty strings.
Tablespace options Tablespace options

View File

@ -160,8 +160,8 @@ dbshell
.. django-admin:: dbshell .. django-admin:: dbshell
Runs the command-line client for the database engine specified in your Runs the command-line client for the database engine specified in your
``DATABASE_ENGINE`` setting, with the connection parameters specified in your ``ENGINE`` setting, with the connection parameters specified in your
``DATABASE_USER``, ``DATABASE_PASSWORD``, etc., settings. ``USER``, ``PASSWORD``, etc., settings.
* For PostgreSQL, this runs the ``psql`` command-line client. * For PostgreSQL, this runs the ``psql`` command-line client.
* For MySQL, this runs the ``mysql`` command-line client. * For MySQL, this runs the ``mysql`` command-line client.
@ -265,7 +265,7 @@ inspectdb
.. django-admin:: inspectdb .. django-admin:: inspectdb
Introspects the database tables in the database pointed-to by the Introspects the database tables in the database pointed-to by the
``DATABASE_NAME`` setting and outputs a Django model module (a ``models.py`` ``NAME`` setting and outputs a Django model module (a ``models.py``
file) to standard output. file) to standard output.
Use this if you have a legacy database with which you'd like to use Django. Use this if you have a legacy database with which you'd like to use Django.

View File

@ -195,41 +195,60 @@ end users) indicating the reason the request was rejected. See
DATABASES DATABASES
--------- ---------
.. versionadded: 1.2
Default: ``{}`` (Empty dictionary) Default: ``{}`` (Empty dictionary)
This is a dictionary containg the settings for all databases to be used with A dictionary containing the settings for all databases to be used with
Django. It is a nested dictionary who's contents maps aliases to a dictionary Django. It is a nested dictionary who's contents maps database aliases
containing the options for an individual database. The following inner options to a dictionary containing the options for an individual database.
are used:
.. deprecated: 1.2 The :setting:`DATABASES` setting must configure a ``default`` database;
any number of additional databases may also be specified.
In versions of Django prior to 1.2 each of the following were The simplest possible settings file is for a single-database setup using
individual settings. The usage of the standalone database settings SQLite. This can be configured using the following::
has been deprecated, and will be removed in Django 1.4. DATABASES = {
'default': {
'BACKEND': 'django.db.backends.sqlite3',
'NAME': 'mydatabase'
}
}
.. setting:: DATABASE_ENGINE For other database backends, or more complex SQLite configurations, other options
will be required. The following inner options are available.
DATABASE_ENGINE .. setting:: ENGINE
~~~~~~~~~~~~~~~
ENGINE
~~~~~~
Default: ``''`` (Empty string) Default: ``''`` (Empty string)
The database backend to use. The built-in database backends are The database backend to use. The built-in database backends are:
``'postgresql_psycopg2'``, ``'postgresql'``, ``'mysql'``, ``'sqlite3'``, and
``'oracle'``. * ``'django.db.backends.postgresql_psycopg2'``
* ``'django.db.backends.postgresql'``
* ``'django.db.backends.mysql'``
* ``'django.db.backends.sqlite3'``
* ``'django.db.backends.oracle'``
You can use a database backend that doesn't ship with Django by setting You can use a database backend that doesn't ship with Django by setting
``DATABASE_ENGINE`` to a fully-qualified path (i.e. ``ENGINE`` to a fully-qualified path (i.e.
``mypackage.backends.whatever``). Writing a whole new database backend from ``mypackage.backends.whatever``). Writing a whole new database backend from
scratch is left as an exercise to the reader; see the other backends for scratch is left as an exercise to the reader; see the other backends for
examples. examples.
.. versionadded:: 1.0 .. note::
Support for external database backends is new in 1.0. Prior to Django 1.2, you could use a short version of the backend name
to reference the built-in database backends (e.g., you could use
``'sqlite3'`` to refer to the SQLite backend). This format has been
deprecated, and will be removed in Django 1.4.
DATABASE_HOST .. setting:: HOST
~~~~~~~~~~~~~
HOST
~~~~
Default: ``''`` (Empty string) Default: ``''`` (Empty string)
@ -239,7 +258,7 @@ localhost. Not used with SQLite.
If this value starts with a forward slash (``'/'``) and you're using MySQL, If this value starts with a forward slash (``'/'``) and you're using MySQL,
MySQL will connect via a Unix socket to the specified socket. For example:: MySQL will connect via a Unix socket to the specified socket. For example::
"DATABASE_HOST": '/var/run/mysql' "HOST": '/var/run/mysql'
If you're using MySQL and this value *doesn't* start with a forward slash, then If you're using MySQL and this value *doesn't* start with a forward slash, then
this value is assumed to be the host. this value is assumed to be the host.
@ -249,8 +268,10 @@ for the connection, rather than a network connection to localhost. If you
explicitly need to use a TCP/IP connection on the local machine with explicitly need to use a TCP/IP connection on the local machine with
PostgreSQL, specify ``localhost`` here. PostgreSQL, specify ``localhost`` here.
DATABASE_NAME .. setting:: NAME
~~~~~~~~~~~~~
NAME
~~~~
Default: ``''`` (Empty string) Default: ``''`` (Empty string)
@ -258,41 +279,48 @@ The name of the database to use. For SQLite, it's the full path to the database
file. When specifying the path, always use forward slashes, even on Windows file. When specifying the path, always use forward slashes, even on Windows
(e.g. ``C:/homes/user/mysite/sqlite3.db``). (e.g. ``C:/homes/user/mysite/sqlite3.db``).
DATABASE_OPTIONS .. setting:: OPTIONS
~~~~~~~~~~~~~~~~
OPTIONS
~~~~~~~
Default: ``{}`` (Empty dictionary) Default: ``{}`` (Empty dictionary)
Extra parameters to use when connecting to the database. Consult backend Extra parameters to use when connecting to the database. Consult backend
module's document for available keywords. module's document for available keywords.
DATABASE_PASSWORD .. setting:: PASSWORD
~~~~~~~~~~~~~~~~~
PASSWORD
~~~~~~~~
Default: ``''`` (Empty string) Default: ``''`` (Empty string)
The password to use when connecting to the database. Not used with SQLite. The password to use when connecting to the database. Not used with SQLite.
DATABASE_PORT .. setting:: PORT
~~~~~~~~~~~~~
PORT
~~~~
Default: ``''`` (Empty string) Default: ``''`` (Empty string)
The port to use when connecting to the database. An empty string means the The port to use when connecting to the database. An empty string means the
default port. Not used with SQLite. default port. Not used with SQLite.
DATABASE_USER .. setting:: USER
~~~~~~~~~~~~~
USER
~~~~
Default: ``''`` (Empty string) Default: ``''`` (Empty string)
The username to use when connecting to the database. Not used with SQLite. The username to use when connecting to the database. Not used with SQLite.
.. setting:: TEST_CHARSET
TEST_DATABASE_CHARSET TEST_CHARSET
~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~
.. versionadded:: 1.0
Default: ``None`` Default: ``None``
@ -306,11 +334,10 @@ MySQL_ (``mysql``) backends.
.. _PostgreSQL: http://www.postgresql.org/docs/8.2/static/multibyte.html .. _PostgreSQL: http://www.postgresql.org/docs/8.2/static/multibyte.html
.. _MySQL: http://www.mysql.org/doc/refman/5.0/en/charset-database.html .. _MySQL: http://www.mysql.org/doc/refman/5.0/en/charset-database.html
.. setting:: TEST_COLLATION
TEST_DATABASE_COLLATION TEST_COLLATION
~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~
.. versionadded:: 1.0
Default: ``None`` Default: ``None``
@ -322,8 +349,10 @@ manual for details).
.. _section 10.3.2: http://www.mysql.org/doc/refman/5.0/en/charset-database.html .. _section 10.3.2: http://www.mysql.org/doc/refman/5.0/en/charset-database.html
TEST_DATABASE_NAME .. setting:: TEST_NAME
~~~~~~~~~~~~~~~~~~
TEST_NAME
~~~~~~~~~
Default: ``None`` Default: ``None``
@ -1292,3 +1321,79 @@ Different locales have different formats. For example, U.S. English would say
See :ttag:`allowed date format strings <now>`. See also ``DATE_FORMAT``, See :ttag:`allowed date format strings <now>`. See also ``DATE_FORMAT``,
``DATETIME_FORMAT``, ``TIME_FORMAT`` and ``MONTH_DAY_FORMAT``. ``DATETIME_FORMAT``, ``TIME_FORMAT`` and ``MONTH_DAY_FORMAT``.
Deprecated settings
===================
.. setting:: DATABASE_ENGINE
DATABASE_ENGINE
---------------
.. deprecated:: 1.2
This setting has been replaced by :setting:`ENGINE` in
:setting:`DATABASES`.
DATABASE_HOST
-------------
.. deprecated:: 1.2
This setting has been replaced by :setting:`HOST` in
:setting:`DATABASES`.
DATABASE_NAME
-------------
.. deprecated:: 1.2
This setting has been replaced by :setting:`NAME` in
:setting:`DATABASES`.
DATABASE_OPTIONS
----------------
.. deprecated:: 1.2
This setting has been replaced by :setting:`OPTIONS` in
:setting:`DATABASES`.
DATABASE_PASSWORD
-----------------
.. deprecated:: 1.2
This setting has been replaced by :setting:`PASSWORD` in
:setting:`DATABASES`.
DATABASE_PORT
-------------
.. deprecated:: 1.2
This setting has been replaced by :setting:`PORT` in
:setting:`DATABASES`.
DATABASE_USER
-------------
.. deprecated:: 1.2
This setting has been replaced by :setting:`USER` in
:setting:`DATABASES`.
TEST_DATABASE_CHARSET
---------------------
.. deprecated:: 1.2
This setting has been replaced by :setting:`TEST_CHARSET` in
:setting:`DATABASES`.
TEST_DATABASE_COLLATION
-----------------------
.. deprecated:: 1.2
This setting has been replaced by :setting:`TEST_COLLATION` in
:setting:`DATABASES`.
TEST_DATABASE_NAME
------------------
.. deprecated:: 1.2
This setting has been replaced by :setting:`TEST_NAME` in
:setting:`DATABASES`.

View File

@ -67,6 +67,72 @@ changes:
__members__ = property(lambda self: self.__dir__()) __members__ = property(lambda self: self.__dir__())
Specifying databases
--------------------
Prior to Django 1.1, Django used a number of settings to control access to a
single database. Django 1.2 introduces support for multiple databases, and as
a result, the way you define database settings has changed.
Previously, there were a number of ``DATABASE_`` settings at the top level of
your settings file. For example::
DATABASE_NAME = 'test_db'
DATABASE_BACKEND = 'postgresl_psycopg2'
DATABASE_USER = 'myusername'
DATABASE_PASSWORD = 's3krit'
These settings are now contained inside a dictionary named
``DATABASES``. Each item in the dictionary corresponds to a single
database connection, with the name ``default`` describing the default
database connection. The setting names have also been shortened to
reflect the fact that they are stored in a dictionary. The sample
settings given previously would now be stored using::
DATABASES = {
'default': {
'NAME': 'test_db',
'BACKEND': 'django.db.backends.postgresl_psycopg2',
'USER': 'myusername',
'PASSWORD': 's3krit',
}
This affects the following settings:
Old setting New Setting
========================================= ===========
:setting:`DATABASE_ENGINE` ENGINE
:setting:`DATABASE_HOST` HOST
:setting:`DATABASE_NAME` NAME
:setting:`DATABASE_OPTIONS` OPTIONS
:setting:`DATABASE_PASSWORD` PASSWORD
:setting:`DATABASE_PORT` PORT
:setting:`DATABASE_USER` USER
:setting:`TEST_DATABASE_CHARSET` TEST_CHARSET
:setting:`TEST_DATABASE_COLLATION` TEST_COLLATION
:setting:`TEST_DATABASE_NAME` TEST_NAME
These changes are also required if you have manually created a database
connection using
In addition to the change in structure, Django 1.2 removes the special
handling for the built-in database backends. All database backends
must now be specified by a fully qualified class name (i.e.,
``django.db.backends.postgresl_psycopg2``, rather than just
``postgresql_psycopg2``)
``__dict__`` on Model instances
-------------------------------
Historically, the ``__dict__`` attribute of a model instance has only contained
attributes corresponding to the fields on a model.
In order to support multiple database configurations, Django 1.2 has
added a ``_state`` attribute to object instances. This attribute will
appear in ``__dict__`` for a model instance. If your code relies on
iterating over __dict__ to obtain a list of fields, you must now
filter out ``_state`` attribute of out ``__dict__``.
.. _deprecated-features-1.2: .. _deprecated-features-1.2:
Features deprecated in 1.2 Features deprecated in 1.2
@ -107,3 +173,12 @@ backend implementations that allow you to send email to a
:ref:`memory<topic-email-memory-backend>` - you can even configure all :ref:`memory<topic-email-memory-backend>` - you can even configure all
email to be :ref:`thrown away<topic-email-console-backend>`. email to be :ref:`thrown away<topic-email-console-backend>`.
Support for multiple databases
------------------------------
Django 1.2 adds the ability to use :ref:`more than one database
<topics-db-multi-db>`in your Django project. Queries can be
issued at a specific database with the `using()` method on
querysets; individual objects can be saved to a specific database
by providing a ``using`` argument when you save the instance.

View File

@ -278,33 +278,35 @@ The test database
----------------- -----------------
Tests that require a database (namely, model tests) will not use your "real" Tests that require a database (namely, model tests) will not use your "real"
(production) database. A separate, blank database is created for the tests. (production) database. Separate, blank databases are created for the tests.
Regardless of whether the tests pass or fail, the test database is destroyed Regardless of whether the tests pass or fail, the test databases are destroyed
when all the tests have been executed. when all the tests have been executed.
By default this test database gets its name by prepending ``test_`` to the By default the test databases get their names by prepending ``test_``
value of the ``DATABASE_NAME`` setting. When using the SQLite database to the value of the :setting:`NAME`` settings for the databased
engine the tests will by default use an in-memory database (i.e., the database defined in :setting:`DATABASES`. When using the SQLite database engine
will be created in memory, bypassing the filesystem entirely!). If you want to the tests will by default use an in-memory database (i.e., the
use a different database name, specify ``TEST_DATABASE_NAME`` in the dictionary database will be created in memory, bypassing the filesystem
for any given database in :setting:`DATABASES`. entirely!). If you want to use a different database name, specify
``TEST_NAME`` in the dictionary for any given database in
:setting:`DATABASES`.
Aside from using a separate database, the test runner will otherwise use all of Aside from using a separate database, the test runner will otherwise
the same database settings you have in your settings file: use all of the same database settings you have in your settings file:
``DATABASE_ENGINE``, ``DATABASE_USER``, ``DATABASE_HOST``, :setting:`ENGINE`, :setting:`USER`, :setting:`HOST`, etc. The test
etc. The test database is created by the user specified by database is created by the user specified by ``USER``, so you'll need
``DATABASE_USER``, so you'll need to make sure that the given user to make sure that the given user account has sufficient privileges to
account has sufficient privileges to create a new database on the system. create a new database on the system.
.. versionadded:: 1.0 .. versionadded:: 1.0
For fine-grained control over the For fine-grained control over the character encoding of your test
character encoding of your test database, use the database, use the :setting:`TEST_CHARSET` option. If you're using
``TEST_DATABASE_CHARSET`` option. If you're using MySQL, you can also MySQL, you can also use the :setting:`TEST_COLLATION` option to
use the ``TEST_DATABASE_COLLATION`` option to control the particular control the particular collation used by the test database. See the
collation used by the test database. See the :ref:`settings documentation :ref:`settings documentation <ref-settings>` for details of these
<ref-settings>` for details of these advanced settings. advanced settings.
Other test conditions Other test conditions
--------------------- ---------------------
@ -1284,16 +1286,17 @@ utility methods in the ``django.test.utils`` module.
.. function:: setup_test_environment() .. function:: setup_test_environment()
Performs any global pre-test setup, such as the installing the Performs any global pre-test setup, such as the installing the
instrumentation of the template rendering system and setting up the dummy instrumentation of the template rendering system and setting up
``SMTPConnection``. the dummy ``SMTPConnection``.
.. function:: teardown_test_environment() .. function:: teardown_test_environment()
Performs any global post-test teardown, such as removing the black magic Performs any global post-test teardown, such as removing the black
hooks into the template system and restoring normal e-mail services. magic hooks into the template system and restoring normal e-mail
services.
The creation module of the database backend (``connection.creation``) also The creation module of the database backend (``connection.creation``)
provides some utilities that can be useful during testing. also provides some utilities that can be useful during testing.
.. function:: create_test_db(verbosity=1, autoclobber=False) .. function:: create_test_db(verbosity=1, autoclobber=False)
@ -1301,27 +1304,29 @@ provides some utilities that can be useful during testing.
``verbosity`` has the same behavior as in ``run_tests()``. ``verbosity`` has the same behavior as in ``run_tests()``.
``autoclobber`` describes the behavior that will occur if a database with ``autoclobber`` describes the behavior that will occur if a
the same name as the test database is discovered: database with the same name as the test database is discovered:
* If ``autoclobber`` is ``False``, the user will be asked to approve * If ``autoclobber`` is ``False``, the user will be asked to
destroying the existing database. ``sys.exit`` is called if the user approve destroying the existing database. ``sys.exit`` is
does not approve. called if the user does not approve.
* If autoclobber is ``True``, the database will be destroyed without * If autoclobber is ``True``, the database will be destroyed
consulting the user. without consulting the user.
Returns the name of the test database that it created. Returns the name of the test database that it created.
``create_test_db()`` has the side effect of modifying ``create_test_db()`` has the side effect of modifying the value of
``settings.DATABASE_NAME`` to match the name of the test database. :setting:`NAME` in :setting:`DATABASES` to match the name of the test
database.
.. versionchanged:: 1.0 .. versionchanged:: 1.0
``create_test_db()`` now returns the name of the test database. ``create_test_db()`` now returns the name of the test database.
.. function:: destroy_test_db(old_database_name, verbosity=1) .. function:: destroy_test_db(old_database_name, verbosity=1)
Destroys the database whose name is in the :setting:`DATABASE_NAME` setting Destroys the database whose name is in stored in :setting:`NAME` in the
and restores the value of :setting:`DATABASE_NAME` to the provided name. :setting:`DATABASES`, and sets :setting:`NAME` to use the
provided name.
``verbosity`` has the same behavior as in ``run_tests()``. ``verbosity`` has the same behavior as in ``run_tests()``.

View File

@ -365,7 +365,7 @@ from django.conf import settings
building_docs = getattr(settings, 'BUILDING_DOCS', False) building_docs = getattr(settings, 'BUILDING_DOCS', False)
if building_docs or settings.DATABASES[DEFAULT_DB_ALIAS]['DATABASE_ENGINE'] == 'postgresql': if building_docs or settings.DATABASES[DEFAULT_DB_ALIAS]['ENGINE'] == 'django.db.backends.postgresql':
__test__['API_TESTS'] += """ __test__['API_TESTS'] += """
# In PostgreSQL, microsecond-level precision is available. # In PostgreSQL, microsecond-level precision is available.
>>> a9 = Article(headline='Article 9', pub_date=datetime(2005, 7, 31, 12, 30, 45, 180)) >>> a9 = Article(headline='Article 9', pub_date=datetime(2005, 7, 31, 12, 30, 45, 180))
@ -374,7 +374,7 @@ if building_docs or settings.DATABASES[DEFAULT_DB_ALIAS]['DATABASE_ENGINE'] == '
datetime.datetime(2005, 7, 31, 12, 30, 45, 180) datetime.datetime(2005, 7, 31, 12, 30, 45, 180)
""" """
if building_docs or settings.DATABASES[DEFAULT_DB_ALIAS]['DATABASE_ENGINE'] == 'mysql': if building_docs or settings.DATABASES[DEFAULT_DB_ALIAS]['ENGINE'] == 'django.db.backends.mysql':
__test__['API_TESTS'] += """ __test__['API_TESTS'] += """
# In MySQL, microsecond-level precision isn't available. You'll lose # In MySQL, microsecond-level precision isn't available. You'll lose
# microsecond-level precision once the data is saved. # microsecond-level precision once the data is saved.

View File

@ -156,7 +156,7 @@ True
# SQLite lets objects be saved with an empty primary key, even though an # SQLite lets objects be saved with an empty primary key, even though an
# integer is expected. So we can't check for an error being raised in that case # integer is expected. So we can't check for an error being raised in that case
# for SQLite. Remove it from the suite for this next bit. # for SQLite. Remove it from the suite for this next bit.
if settings.DATABASES[DEFAULT_DB_ALIAS]['DATABASE_ENGINE'] != 'sqlite3': if settings.DATABASES[DEFAULT_DB_ALIAS]['ENGINE'] != 'django.db.backends.sqlite3':
__test__["API_TESTS"] += """ __test__["API_TESTS"] += """
# The primary key must be specified, so an error is raised if you try to create # The primary key must be specified, so an error is raised if you try to create
# an object without it. # an object without it.

View File

@ -100,7 +100,7 @@ __test__ = {'API_TESTS': """
# Database flushing does not work on MySQL with the default storage engine # Database flushing does not work on MySQL with the default storage engine
# because it requires transaction support. # because it requires transaction support.
if settings.DATABASES[DEFAULT_DB_ALIAS]['DATABASE_ENGINE'] != 'mysql': if settings.DATABASES[DEFAULT_DB_ALIAS]['ENGINE'] != 'django.db.backends.mysql':
__test__['API_TESTS'] += \ __test__['API_TESTS'] += \
""" """
# Reset the database representation of this app. This will delete all data. # Reset the database representation of this app. This will delete all data.

View File

@ -43,7 +43,9 @@ False
True True
"""} """}
if settings.DATABASES[DEFAULT_DB_ALIAS]['DATABASE_ENGINE'] in ('postgresql', 'postgresql_pysycopg2'): if settings.DATABASES[DEFAULT_DB_ALIAS]['ENGINE'] in (
'django.db.backends.postgresql',
'django.db.backends.postgresql_pysycopg2'):
__test__['API_TESTS'] += r""" __test__['API_TESTS'] += r"""
# text matching tests for PostgreSQL 8.3 # text matching tests for PostgreSQL 8.3
>>> Article.objects.filter(id__iexact='1') >>> Article.objects.filter(id__iexact='1')
@ -399,7 +401,7 @@ FieldError: Join on field 'headline' not permitted. Did you misspell 'starts' fo
""" """
if settings.DATABASES[DEFAULT_DB_ALIAS]['DATABASE_ENGINE'] != 'mysql': if settings.DATABASES[DEFAULT_DB_ALIAS]['ENGINE'] != 'django.db.backends.mysql':
__test__['API_TESTS'] += r""" __test__['API_TESTS'] += r"""
# grouping and backreferences # grouping and backreferences
>>> Article.objects.filter(headline__regex=r'b(.).*b\1') >>> Article.objects.filter(headline__regex=r'b(.).*b\1')

View File

@ -28,7 +28,7 @@ from django.conf import settings
building_docs = getattr(settings, 'BUILDING_DOCS', False) building_docs = getattr(settings, 'BUILDING_DOCS', False)
if building_docs or settings.DATABASES[DEFAULT_DB_ALIAS]['DATABASE_ENGINE'] != 'mysql': if building_docs or settings.DATABASES[DEFAULT_DB_ALIAS]['ENGINE'] != 'django.db.backends.mysql':
__test__['API_TESTS'] += """ __test__['API_TESTS'] += """
# the default behavior is to autocommit after each save() action # the default behavior is to autocommit after each save() action
>>> def create_a_reporter_then_fail(first, last): >>> def create_a_reporter_then_fail(first, last):

View File

@ -61,23 +61,25 @@ class AdminScriptTestCase(unittest.TestCase):
except OSError: except OSError:
pass pass
def _ext_backend_path(self): def _ext_backend_paths(self):
""" """
Returns the path for the external backend package, or None if no Returns the paths for any external backend packages.
external backend is detected.
""" """
paths = []
first_package_re = re.compile(r'(^[^\.]+)\.') first_package_re = re.compile(r'(^[^\.]+)\.')
result = first_package_re.findall(settings.DATABASE_ENGINE) for backend in settings.DATABASES.values():
if result: result = first_package_re.findall(backend['ENGINE'])
if result and result != 'django':
backend_pkg = __import__(result[0]) backend_pkg = __import__(result[0])
backend_dir = os.path.dirname(backend_pkg.__file__) backend_dir = os.path.dirname(backend_pkg.__file__)
return os.path.dirname(backend_dir) paths.append(os.path.dirname(backend_dir))
return paths
def run_test(self, script, args, settings_file=None, apps=None): def run_test(self, script, args, settings_file=None, apps=None):
test_dir = os.path.dirname(os.path.dirname(__file__)) test_dir = os.path.dirname(os.path.dirname(__file__))
project_dir = os.path.dirname(test_dir) project_dir = os.path.dirname(test_dir)
base_dir = os.path.dirname(project_dir) base_dir = os.path.dirname(project_dir)
ext_backend_base_dir = self._ext_backend_path() ext_backend_base_dirs = self._ext_backend_paths()
# Remember the old environment # Remember the old environment
old_django_settings_module = os.environ.get('DJANGO_SETTINGS_MODULE', None) old_django_settings_module = os.environ.get('DJANGO_SETTINGS_MODULE', None)
@ -95,8 +97,7 @@ class AdminScriptTestCase(unittest.TestCase):
elif 'DJANGO_SETTINGS_MODULE' in os.environ: elif 'DJANGO_SETTINGS_MODULE' in os.environ:
del os.environ['DJANGO_SETTINGS_MODULE'] del os.environ['DJANGO_SETTINGS_MODULE']
python_path = [test_dir, base_dir] python_path = [test_dir, base_dir]
if ext_backend_base_dir: python_path.extend(ext_backend_base_dirs)
python_path.append(ext_backend_base_dir)
os.environ[python_path_var_name] = os.pathsep.join(python_path) os.environ[python_path_var_name] = os.pathsep.join(python_path)
# Build the command line # Build the command line

View File

@ -327,7 +327,7 @@ def run_stddev_tests():
Stddev and Variance are not guaranteed to be available for SQLite, and Stddev and Variance are not guaranteed to be available for SQLite, and
are not available for PostgreSQL before 8.2. are not available for PostgreSQL before 8.2.
""" """
if settings.DATABASES[DEFAULT_DB_ALIAS]['DATABASE_ENGINE'] == 'sqlite3': if settings.DATABASES[DEFAULT_DB_ALIAS]['ENGINE'] == 'django.db.backends.sqlite3':
return False return False
class StdDevPop(object): class StdDevPop(object):

View File

@ -10,7 +10,7 @@ class Callproc(unittest.TestCase):
def test_dbms_session(self): def test_dbms_session(self):
# If the backend is Oracle, test that we can call a standard # If the backend is Oracle, test that we can call a standard
# stored procedure through our cursor wrapper. # stored procedure through our cursor wrapper.
if settings.DATABASES[DEFAULT_DB_ALIAS]['DATABASE_ENGINE'] == 'oracle': if settings.DATABASES[DEFAULT_DB_ALIAS]['ENGINE'] == 'django.db.backends.oracle':
convert_unicode = backend.convert_unicode convert_unicode = backend.convert_unicode
cursor = connection.cursor() cursor = connection.cursor()
cursor.callproc(convert_unicode('DBMS_SESSION.SET_IDENTIFIER'), cursor.callproc(convert_unicode('DBMS_SESSION.SET_IDENTIFIER'),
@ -39,7 +39,7 @@ class LongString(unittest.TestCase):
def test_long_string(self): def test_long_string(self):
# If the backend is Oracle, test that we can save a text longer # If the backend is Oracle, test that we can save a text longer
# than 4000 chars and read it properly # than 4000 chars and read it properly
if settings.DATABASES[DEFAULT_DB_ALIAS]['DATABASE_ENGINE'] == 'oracle': if settings.DATABASES[DEFAULT_DB_ALIAS]['ENGINE'] == 'django.db.backends.oracle':
c = connection.cursor() c = connection.cursor()
c.execute('CREATE TABLE ltext ("TEXT" NCLOB)') c.execute('CREATE TABLE ltext ("TEXT" NCLOB)')
long_str = ''.join([unicode(x) for x in xrange(4000)]) long_str = ''.join([unicode(x) for x in xrange(4000)])
@ -79,7 +79,7 @@ __test__ = {'API_TESTS': """
# Unfortunately with sqlite3 the in-memory test database cannot be # Unfortunately with sqlite3 the in-memory test database cannot be
# closed, and so it cannot be re-opened during testing, and so we # closed, and so it cannot be re-opened during testing, and so we
# sadly disable this test for now. # sadly disable this test for now.
if settings.DATABASES[DEFAULT_DB_ALIAS]['DATABASE_ENGINE'] != 'sqlite3': if settings.DATABASES[DEFAULT_DB_ALIAS]['ENGINE'] != 'django.db.backends.sqlite3':
__test__['API_TESTS'] += """ __test__['API_TESTS'] += """
>>> connection_created.connect(connection_created_test) >>> connection_created.connect(connection_created_test)
>>> connection.close() # Ensure the connection is closed >>> connection.close() # Ensure the connection is closed

View File

@ -93,7 +93,7 @@ u'Outstanding'
# Regression test for #8354: the MySQL backend should raise an error if given # Regression test for #8354: the MySQL backend should raise an error if given
# a timezone-aware datetime object. # a timezone-aware datetime object.
if settings.DATABASES[DEFAULT_DB_ALIAS]['DATABASE_ENGINE'] == 'mysql': if settings.DATABASES[DEFAULT_DB_ALIAS]['ENGINE'] == 'django.db.backends.mysql':
__test__['API_TESTS'] += """ __test__['API_TESTS'] += """
>>> from django.utils import tzinfo >>> from django.utils import tzinfo
>>> dt = datetime.datetime(2008, 8, 31, 16, 20, tzinfo=tzinfo.FixedOffset(0)) >>> dt = datetime.datetime(2008, 8, 31, 16, 20, tzinfo=tzinfo.FixedOffset(0))

View File

@ -8,18 +8,18 @@ class Book(models.Model):
# Can't run this test under SQLite, because you can't # Can't run this test under SQLite, because you can't
# get two connections to an in-memory database. # get two connections to an in-memory database.
if settings.DATABASES[DEFAULT_DB_ALIAS]['DATABASE_ENGINE'] != 'sqlite3': if settings.DATABASES[DEFAULT_DB_ALIAS]['ENGINE'] != 'django.db.backends.sqlite3':
class DeleteLockingTest(TransactionTestCase): class DeleteLockingTest(TransactionTestCase):
def setUp(self): def setUp(self):
# Create a second connection to the database # Create a second connection to the database
conn_settings = settings.DATABASES[DEFAULT_DB_ALIAS] conn_settings = settings.DATABASES[DEFAULT_DB_ALIAS]
self.conn2 = backend.DatabaseWrapper({ self.conn2 = backend.DatabaseWrapper({
'DATABASE_HOST': conn_settings['DATABASE_HOST'], 'HOST': conn_settings['HOST'],
'DATABASE_NAME': conn_settings['DATABASE_NAME'], 'NAME': conn_settings['NAME'],
'DATABASE_OPTIONS': conn_settings['DATABASE_OPTIONS'], 'OPTIONS': conn_settings['OPTIONS'],
'DATABASE_PASSWORD': conn_settings['DATABASE_PASSWORD'], 'PASSWORD': conn_settings['PASSWORD'],
'DATABASE_PORT': conn_settings['DATABASE_PORT'], 'PORT': conn_settings['PORT'],
'DATABASE_USER': conn_settings['DATABASE_USER'], 'USER': conn_settings['USER'],
'TIME_ZONE': settings.TIME_ZONE, 'TIME_ZONE': settings.TIME_ZONE,
}) })

View File

@ -121,7 +121,7 @@ Complex expressions of different connection types are possible.
"""} """}
# Oracle doesn't support the Bitwise OR operator. # Oracle doesn't support the Bitwise OR operator.
if settings.DATABASES[DEFAULT_DB_ALIAS]['DATABASE_ENGINE'] != 'oracle': if settings.DATABASES[DEFAULT_DB_ALIAS]['ENGINE'] != 'django.db.backends.oracle':
__test__['API_TESTS'] += """ __test__['API_TESTS'] += """
>>> _ = Number.objects.filter(pk=n.pk).update(integer=42, float=15.5) >>> _ = Number.objects.filter(pk=n.pk).update(integer=42, float=15.5)

View File

@ -35,7 +35,7 @@ class Stuff(models.Model):
# Oracle doesn't distinguish between None and the empty string. # Oracle doesn't distinguish between None and the empty string.
# This hack makes the test case pass using Oracle. # This hack makes the test case pass using Oracle.
name = self.name name = self.name
if (settings.DATABASES[DEFAULT_DB_ALIAS]['DATABASE_ENGINE'] == 'oracle' if (settings.DATABASES[DEFAULT_DB_ALIAS]['ENGINE'] == 'django.db.backends.oracle'
and name == u''): and name == u''):
name = None name = None
return unicode(name) + u' is owned by ' + unicode(self.owner) return unicode(name) + u' is owned by ' + unicode(self.owner)

View File

@ -80,7 +80,7 @@ class IntrospectionTests(TestCase):
['IntegerField', 'CharField', 'CharField', 'CharField']) ['IntegerField', 'CharField', 'CharField', 'CharField'])
# Regression test for #9991 - 'real' types in postgres # Regression test for #9991 - 'real' types in postgres
if settings.DATABASES[DEFAULT_DB_ALIAS]['DATABASE_ENGINE'].startswith('postgresql'): if settings.DATABASES[DEFAULT_DB_ALIAS]['ENGINE'].startswith('django.db.backends.postgresql'):
def test_postgresql_real_type(self): def test_postgresql_real_type(self):
cursor = connection.cursor() cursor = connection.cursor()
cursor.execute("CREATE TABLE django_ixn_real_test_table (number REAL);") cursor.execute("CREATE TABLE django_ixn_real_test_table (number REAL);")

View File

@ -149,7 +149,9 @@ datetime.datetime(2000, 1, 1, 6, 1, 1)
"""} """}
if settings.DATABASES[DEFAULT_DB_ALIAS]['DATABASE_ENGINE'] not in ("mysql", "oracle"): if settings.DATABASES[DEFAULT_DB_ALIAS]['ENGINE'] not in (
"django.db.backends.mysql",
"django.db.backends.oracle"):
__test__["timezone-tests"] = """ __test__["timezone-tests"] = """
# Saving an updating with timezone-aware datetime Python objects. Regression # Saving an updating with timezone-aware datetime Python objects. Regression
# test for #10443. # test for #10443.

View File

@ -1223,13 +1223,13 @@ FieldError: Infinite loop caused by ordering.
# In Oracle, we expect a null CharField to return u'' instead of None. # In Oracle, we expect a null CharField to return u'' instead of None.
if settings.DATABASES[DEFAULT_DB_ALIAS]['DATABASE_ENGINE'] == "oracle": if settings.DATABASES[DEFAULT_DB_ALIAS]['ENGINE'] == "django.db.backends.oracle":
__test__["API_TESTS"] = __test__["API_TESTS"].replace("<NONE_OR_EMPTY_UNICODE>", "u''") __test__["API_TESTS"] = __test__["API_TESTS"].replace("<NONE_OR_EMPTY_UNICODE>", "u''")
else: else:
__test__["API_TESTS"] = __test__["API_TESTS"].replace("<NONE_OR_EMPTY_UNICODE>", "None") __test__["API_TESTS"] = __test__["API_TESTS"].replace("<NONE_OR_EMPTY_UNICODE>", "None")
if settings.DATABASES[DEFAULT_DB_ALIAS]['DATABASE_ENGINE'] == "mysql": if settings.DATABASES[DEFAULT_DB_ALIAS]['ENGINE'] == "django.db.backends.mysql":
__test__["API_TESTS"] += """ __test__["API_TESTS"] += """
When grouping without specifying ordering, we add an explicit "ORDER BY NULL" When grouping without specifying ordering, we add an explicit "ORDER BY NULL"
portion in MySQL to prevent unnecessary sorting. portion in MySQL to prevent unnecessary sorting.

View File

@ -326,7 +326,7 @@ The end."""),
# Because Oracle treats the empty string as NULL, Oracle is expected to fail # Because Oracle treats the empty string as NULL, Oracle is expected to fail
# when field.empty_strings_allowed is True and the value is None; skip these # when field.empty_strings_allowed is True and the value is None; skip these
# tests. # tests.
if settings.DATABASES[DEFAULT_DB_ALIAS]['DATABASE_ENGINE'] == 'oracle': if settings.DATABASES[DEFAULT_DB_ALIAS]['ENGINE'] == 'django.db.backends.oracle':
test_data = [data for data in test_data test_data = [data for data in test_data
if not (data[0] == data_obj and if not (data[0] == data_obj and
data[2]._meta.get_field('data').empty_strings_allowed and data[2]._meta.get_field('data').empty_strings_allowed and
@ -335,7 +335,7 @@ if settings.DATABASES[DEFAULT_DB_ALIAS]['DATABASE_ENGINE'] == 'oracle':
# Regression test for #8651 -- a FK to an object iwth PK of 0 # Regression test for #8651 -- a FK to an object iwth PK of 0
# This won't work on MySQL since it won't let you create an object # This won't work on MySQL since it won't let you create an object
# with a primary key of 0, # with a primary key of 0,
if settings.DATABASES[DEFAULT_DB_ALIAS]['DATABASE_ENGINE'] != 'mysql': if settings.DATABASES[DEFAULT_DB_ALIAS]['ENGINE'] != 'django.db.backends.mysql':
test_data.extend([ test_data.extend([
(data_obj, 0, Anchor, "Anchor 0"), (data_obj, 0, Anchor, "Anchor 0"),
(fk_obj, 465, FKData, 0), (fk_obj, 465, FKData, 0),

View File

@ -89,7 +89,6 @@ def django_tests(verbosity, interactive, test_labels):
from django.conf import settings from django.conf import settings
old_installed_apps = settings.INSTALLED_APPS old_installed_apps = settings.INSTALLED_APPS
old_test_database_name = settings.TEST_DATABASE_NAME
old_root_urlconf = getattr(settings, "ROOT_URLCONF", "") old_root_urlconf = getattr(settings, "ROOT_URLCONF", "")
old_template_dirs = settings.TEMPLATE_DIRS old_template_dirs = settings.TEMPLATE_DIRS
old_use_i18n = settings.USE_I18N old_use_i18n = settings.USE_I18N