| 1 | from django.conf import settings
|
|---|
| 2 | from django.core import signals
|
|---|
| 3 | from django.core.exceptions import ImproperlyConfigured
|
|---|
| 4 | from django.db.utils import ConnectionHandler, ConnectionRouter, load_backend, DEFAULT_DB_ALIAS, \
|
|---|
| 5 | DatabaseError, IntegrityError
|
|---|
| 6 | from django.utils.functional import curry
|
|---|
| 7 |
|
|---|
| 8 | __all__ = ('backend', 'connection', 'connections', 'router', 'DatabaseError',
|
|---|
| 9 | 'IntegrityError', 'DEFAULT_DB_ALIAS')
|
|---|
| 10 |
|
|---|
| 11 |
|
|---|
| 12 | # For backwards compatibility - Port any old database settings over to
|
|---|
| 13 | # the new values.
|
|---|
| 14 | if not settings.DATABASES:
|
|---|
| 15 | if settings.DATABASE_ENGINE:
|
|---|
| 16 | import warnings
|
|---|
| 17 | warnings.warn(
|
|---|
| 18 | "settings.DATABASE_* is deprecated; use settings.DATABASES instead.",
|
|---|
| 19 | DeprecationWarning
|
|---|
| 20 | )
|
|---|
| 21 |
|
|---|
| 22 | settings.DATABASES[DEFAULT_DB_ALIAS] = {
|
|---|
| 23 | 'ENGINE': settings.DATABASE_ENGINE,
|
|---|
| 24 | 'HOST': settings.DATABASE_HOST,
|
|---|
| 25 | 'NAME': settings.DATABASE_NAME,
|
|---|
| 26 | 'OPTIONS': settings.DATABASE_OPTIONS,
|
|---|
| 27 | 'PASSWORD': settings.DATABASE_PASSWORD,
|
|---|
| 28 | 'PORT': settings.DATABASE_PORT,
|
|---|
| 29 | 'USER': settings.DATABASE_USER,
|
|---|
| 30 | 'TEST_CHARSET': settings.TEST_DATABASE_CHARSET,
|
|---|
| 31 | 'TEST_COLLATION': settings.TEST_DATABASE_COLLATION,
|
|---|
| 32 | 'TEST_NAME': settings.TEST_DATABASE_NAME,
|
|---|
| 33 | }
|
|---|
| 34 |
|
|---|
| 35 | if DEFAULT_DB_ALIAS not in settings.DATABASES:
|
|---|
| 36 | raise ImproperlyConfigured("You must define a '%s' database" % DEFAULT_DB_ALIAS)
|
|---|
| 37 |
|
|---|
| 38 | for alias, database in settings.DATABASES.items():
|
|---|
| 39 | if 'ENGINE' not in database:
|
|---|
| 40 | raise ImproperlyConfigured("You must specify a 'ENGINE' for database '%s'" % alias)
|
|---|
| 41 | if database['ENGINE'] in ("postgresql", "postgresql_psycopg2", "sqlite3", "mysql", "oracle"):
|
|---|
| 42 | import warnings
|
|---|
| 43 | if 'django.contrib.gis' in settings.INSTALLED_APPS:
|
|---|
| 44 | warnings.warn(
|
|---|
| 45 | "django.contrib.gis is now implemented as a full database backend. "
|
|---|
| 46 | "Modify ENGINE in the %s database configuration to select "
|
|---|
| 47 | "a backend from 'django.contrib.gis.db.backends'" % alias,
|
|---|
| 48 | DeprecationWarning
|
|---|
| 49 | )
|
|---|
| 50 | if database['ENGINE'] == 'postgresql_psycopg2':
|
|---|
| 51 | full_engine = 'django.contrib.gis.db.backends.postgis'
|
|---|
| 52 | elif database['ENGINE'] == 'sqlite3':
|
|---|
| 53 | full_engine = 'django.contrib.gis.db.backends.spatialite'
|
|---|
| 54 | else:
|
|---|
| 55 | full_engine = 'django.contrib.gis.db.backends.%s' % database['ENGINE']
|
|---|
| 56 | else:
|
|---|
| 57 | warnings.warn(
|
|---|
| 58 | "Short names for ENGINE in database configurations are deprecated. "
|
|---|
| 59 | "Prepend %s.ENGINE with 'django.db.backends.'" % alias,
|
|---|
| 60 | DeprecationWarning
|
|---|
| 61 | )
|
|---|
| 62 | full_engine = "django.db.backends.%s" % database['ENGINE']
|
|---|
| 63 | database['ENGINE'] = full_engine
|
|---|
| 64 |
|
|---|
| 65 | connections = ConnectionHandler(settings.DATABASES)
|
|---|
| 66 |
|
|---|
| 67 | router = ConnectionRouter(settings.DATABASE_ROUTERS)
|
|---|
| 68 |
|
|---|
| 69 | # `connection`, `DatabaseError` and `IntegrityError` are convenient aliases
|
|---|
| 70 | # for backend bits.
|
|---|
| 71 |
|
|---|
| 72 | # DatabaseWrapper.__init__() takes a dictionary, not a settings module, so
|
|---|
| 73 | # we manually create the dictionary from the settings, passing only the
|
|---|
| 74 | # settings that the database backends care about. Note that TIME_ZONE is used
|
|---|
| 75 | # by the PostgreSQL backends.
|
|---|
| 76 | # we load all these up for backwards compatibility, you should use
|
|---|
| 77 | # connections['default'] instead.
|
|---|
| 78 | connection = connections[DEFAULT_DB_ALIAS]
|
|---|
| 79 | backend = load_backend(connection.settings_dict['ENGINE'])
|
|---|
| 80 |
|
|---|
| 81 | # Register an event that closes the database connection
|
|---|
| 82 | # when a Django request is finished.
|
|---|
| 83 | def close_connection(**kwargs):
|
|---|
| 84 | for conn in connections.all():
|
|---|
| 85 | conn.close()
|
|---|
| 86 | signals.request_finished.connect(close_connection)
|
|---|
| 87 |
|
|---|
| 88 | # Register an event that resets connection.queries
|
|---|
| 89 | # when a Django request is started.
|
|---|
| 90 | def reset_queries(**kwargs):
|
|---|
| 91 | for conn in connections.all():
|
|---|
| 92 | conn.queries = []
|
|---|
| 93 | signals.request_started.connect(reset_queries)
|
|---|
| 94 |
|
|---|
| 95 | # Register an event that rolls back the connections
|
|---|
| 96 | # when a Django request has an exception.
|
|---|
| 97 | def _rollback_on_exception(**kwargs):
|
|---|
| 98 | from django.db import transaction
|
|---|
| 99 | for conn in connections:
|
|---|
| 100 | try:
|
|---|
| 101 | transaction.rollback_unless_managed(using=conn)
|
|---|
| 102 | except DatabaseError:
|
|---|
| 103 | pass
|
|---|
| 104 | signals.got_request_exception.connect(_rollback_on_exception)
|
|---|