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