Fixed #5454: settings.DATABASE_BACKEND may now refer to an external package (i.e. one located outside the Django source. Thanks, George Vilches.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@6316 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Jacob Kaplan-Moss 2007-09-15 19:25:20 +00:00
parent 201a6cc192
commit 07447a0f56
2 changed files with 45 additions and 19 deletions

View File

@ -1,6 +1,9 @@
import os
from django.conf import settings from django.conf import settings
from django.core import signals from django.core import signals
from django.core.exceptions import ImproperlyConfigured
from django.dispatch import dispatcher from django.dispatch import dispatcher
from django.utils.functional import curry
__all__ = ('backend', 'connection', 'DatabaseError', 'IntegrityError') __all__ = ('backend', 'connection', 'DatabaseError', 'IntegrityError')
@ -8,12 +11,19 @@ if not settings.DATABASE_ENGINE:
settings.DATABASE_ENGINE = 'dummy' settings.DATABASE_ENGINE = 'dummy'
try: try:
backend = __import__('django.db.backends.%s.base' % settings.DATABASE_ENGINE, {}, {}, ['']) # Most of the time, the database backend will be one of the official
# backends that ships with Django, so look there first.
_import_path = 'django.db.backends.'
backend = __import__('%s%s.base' % (_import_path, settings.DATABASE_ENGINE), {}, {}, [''])
except ImportError, e: except ImportError, e:
# If the import failed, we might be looking for a database backend
# distributed external to Django. So we'll try that next.
try:
_import_path = ''
backend = __import__('%s.base' % settings.DATABASE_ENGINE, {}, {}, [''])
except ImportError, e_user:
# The database backend wasn't found. Display a helpful error message # The database backend wasn't found. Display a helpful error message
# listing all possible database backends. # listing all possible (built-in) database backends.
from django.core.exceptions import ImproperlyConfigured
import os
backend_dir = os.path.join(__path__[0], 'backends') backend_dir = os.path.join(__path__[0], 'backends')
available_backends = [f for f in os.listdir(backend_dir) if not f.startswith('_') and not f.startswith('.') and not f.endswith('.py') and not f.endswith('.pyc')] available_backends = [f for f in os.listdir(backend_dir) if not f.startswith('_') and not f.startswith('.') and not f.endswith('.py') and not f.endswith('.pyc')]
available_backends.sort() available_backends.sort()
@ -23,10 +33,21 @@ except ImportError, e:
else: else:
raise # If there's some other error, this must be an error in Django itself. raise # If there's some other error, this must be an error in Django itself.
get_introspection_module = lambda: __import__('django.db.backends.%s.introspection' % settings.DATABASE_ENGINE, {}, {}, ['']) def _import_database_module(import_path='', module_name=''):
get_creation_module = lambda: __import__('django.db.backends.%s.creation' % settings.DATABASE_ENGINE, {}, {}, ['']) """Lazyily import a database module when requested."""
runshell = lambda: __import__('django.db.backends.%s.client' % settings.DATABASE_ENGINE, {}, {}, ['']).runshell() return __import__('%s%s.%s' % (_import_path, settings.DATABASE_ENGINE, module_name), {}, {}, [''])
# We don't want to import the introspect/creation modules unless
# someone asks for 'em, so lazily load them on demmand.
get_introspection_module = curry(_import_database_module, _import_path, 'introspection')
get_creation_module = curry(_import_database_module, _import_path, 'creation')
# We want runshell() to work the same way, but we have to treat it a
# little differently (since it just runs instead of returning a module like
# the above) and wrap the lazily-loaded runshell() method.
runshell = lambda: _import_database_module(_import_path, "client").runshell()
# Convenient aliases for backend bits.
connection = backend.DatabaseWrapper(**settings.DATABASE_OPTIONS) connection = backend.DatabaseWrapper(**settings.DATABASE_OPTIONS)
DatabaseError = backend.DatabaseError DatabaseError = backend.DatabaseError
IntegrityError = backend.IntegrityError IntegrityError = backend.IntegrityError

View File

@ -253,9 +253,14 @@ DATABASE_ENGINE
Default: ``''`` (Empty string) Default: ``''`` (Empty string)
The database backend to use. Either ``'postgresql_psycopg2'``, The database backend to use. The build-in database backends are
``'postgresql'``, ``'mysql'``, ``'mysql_old'``, ``'sqlite3'``, ``'postgresql_psycopg2'``, ``'postgresql'``, ``'mysql'``, ``'mysql_old'``,
``'oracle'``, or ``'ado_mssql'``. ``'sqlite3'``, ``'oracle'``, or ``'ado_mssql'``.
You can also use a database backend that doesn't ship with Django by
setting ``DATABASE_ENGINE`` to a fully-qualified path (i.e.
``mypackage.backends.whatever``). Writing a whole new database backend from
scratch is left as an exercise to the reader.
DATABASE_HOST DATABASE_HOST
------------- -------------