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:
parent
3e6ae729bc
commit
4e36fffab2
3
TODO
3
TODO
@ -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?
|
||||||
|
@ -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.
|
||||||
|
@ -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)'
|
||||||
|
@ -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
|
||||||
|
@ -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'
|
||||||
|
|
||||||
|
@ -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):
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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)
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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]
|
||||||
|
@ -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:
|
||||||
|
@ -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):
|
||||||
|
@ -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
|
||||||
|
@ -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:
|
||||||
|
@ -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))
|
||||||
|
@ -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:
|
||||||
|
@ -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 ''
|
||||||
|
@ -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)
|
||||||
|
@ -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):
|
||||||
|
@ -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:
|
||||||
|
@ -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:
|
||||||
|
@ -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
|
||||||
|
@ -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:
|
||||||
|
@ -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):
|
||||||
|
@ -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>
|
||||||
|
@ -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'
|
||||||
|
@ -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``.
|
||||||
|
@ -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
|
||||||
========================
|
========================
|
||||||
|
@ -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
|
||||||
|
@ -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::
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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.
|
||||||
|
@ -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`.
|
||||||
|
|
||||||
|
@ -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.
|
||||||
|
|
||||||
|
@ -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()``.
|
||||||
|
@ -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.
|
||||||
|
@ -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.
|
||||||
|
@ -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.
|
||||||
|
@ -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')
|
||||||
|
@ -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):
|
||||||
|
@ -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'])
|
||||||
backend_pkg = __import__(result[0])
|
if result and result != 'django':
|
||||||
backend_dir = os.path.dirname(backend_pkg.__file__)
|
backend_pkg = __import__(result[0])
|
||||||
return os.path.dirname(backend_dir)
|
backend_dir = os.path.dirname(backend_pkg.__file__)
|
||||||
|
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
|
||||||
|
@ -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):
|
||||||
|
@ -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
|
||||||
|
@ -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))
|
||||||
|
@ -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,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -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)
|
||||||
|
@ -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)
|
||||||
|
@ -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);")
|
||||||
|
@ -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.
|
||||||
|
@ -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.
|
||||||
|
@ -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),
|
||||||
|
@ -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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user