web/lib/django/db/__init__.py
changeset 29 cc9b7e14412b
parent 0 0d40e90630ef
equal deleted inserted replaced
28:b758351d191f 29:cc9b7e14412b
     1 import os
       
     2 from django.conf import settings
     1 from django.conf import settings
     3 from django.core import signals
     2 from django.core import signals
     4 from django.core.exceptions import ImproperlyConfigured
     3 from django.core.exceptions import ImproperlyConfigured
       
     4 from django.db.utils import ConnectionHandler, ConnectionRouter, load_backend, DEFAULT_DB_ALIAS, \
       
     5                             DatabaseError, IntegrityError
     5 from django.utils.functional import curry
     6 from django.utils.functional import curry
     6 from django.utils.importlib import import_module
       
     7 
     7 
     8 __all__ = ('backend', 'connection', 'DatabaseError', 'IntegrityError')
     8 __all__ = ('backend', 'connection', 'connections', 'router', 'DatabaseError',
       
     9     'IntegrityError', 'DEFAULT_DB_ALIAS')
     9 
    10 
    10 if not settings.DATABASE_ENGINE:
       
    11     settings.DATABASE_ENGINE = 'dummy'
       
    12 
    11 
    13 def load_backend(backend_name):
    12 # For backwards compatibility - Port any old database settings over to
    14     try:
    13 # the new values.
    15         # Most of the time, the database backend will be one of the official
    14 if not settings.DATABASES:
    16         # backends that ships with Django, so look there first.
    15     import warnings
    17         return import_module('.base', 'django.db.backends.%s' % backend_name)
    16     warnings.warn(
    18     except ImportError, e:
    17         "settings.DATABASE_* is deprecated; use settings.DATABASES instead.",
    19         # If the import failed, we might be looking for a database backend
    18         PendingDeprecationWarning
    20         # distributed external to Django. So we'll try that next.
    19     )
    21         try:
    20 
    22             return import_module('.base', backend_name)
    21     settings.DATABASES[DEFAULT_DB_ALIAS] = {
    23         except ImportError, e_user:
    22         'ENGINE': settings.DATABASE_ENGINE,
    24             # The database backend wasn't found. Display a helpful error message
    23         'HOST': settings.DATABASE_HOST,
    25             # listing all possible (built-in) database backends.
    24         'NAME': settings.DATABASE_NAME,
    26             backend_dir = os.path.join(__path__[0], 'backends')
    25         'OPTIONS': settings.DATABASE_OPTIONS,
    27             try:
    26         'PASSWORD': settings.DATABASE_PASSWORD,
    28                 available_backends = [f for f in os.listdir(backend_dir)
    27         'PORT': settings.DATABASE_PORT,
    29                         if os.path.isdir(os.path.join(backend_dir, f))
    28         'USER': settings.DATABASE_USER,
    30                         and not f.startswith('.')]
    29         'TEST_CHARSET': settings.TEST_DATABASE_CHARSET,
    31             except EnvironmentError:
    30         'TEST_COLLATION': settings.TEST_DATABASE_COLLATION,
    32                 available_backends = []
    31         'TEST_NAME': settings.TEST_DATABASE_NAME,
    33             available_backends.sort()
    32     }
    34             if backend_name not in available_backends:
    33 
    35                 error_msg = "%r isn't an available database backend. Available options are: %s\nError was: %s" % \
    34 if DEFAULT_DB_ALIAS not in settings.DATABASES:
    36                     (backend_name, ", ".join(map(repr, available_backends)), e_user)
    35     raise ImproperlyConfigured("You must default a '%s' database" % DEFAULT_DB_ALIAS)
    37                 raise ImproperlyConfigured(error_msg)
    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'
    38             else:
    51             else:
    39                 raise # If there's some other error, this must be an error in Django itself.
    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
    40 
    61 
    41 backend = load_backend(settings.DATABASE_ENGINE)
    62 connections = ConnectionHandler(settings.DATABASES)
       
    63 
       
    64 router = ConnectionRouter(settings.DATABASE_ROUTERS)
    42 
    65 
    43 # `connection`, `DatabaseError` and `IntegrityError` are convenient aliases
    66 # `connection`, `DatabaseError` and `IntegrityError` are convenient aliases
    44 # for backend bits.
    67 # for backend bits.
    45 
    68 
    46 # DatabaseWrapper.__init__() takes a dictionary, not a settings module, so
    69 # DatabaseWrapper.__init__() takes a dictionary, not a settings module, so
    47 # we manually create the dictionary from the settings, passing only the
    70 # we manually create the dictionary from the settings, passing only the
    48 # settings that the database backends care about. Note that TIME_ZONE is used
    71 # settings that the database backends care about. Note that TIME_ZONE is used
    49 # by the PostgreSQL backends.
    72 # by the PostgreSQL backends.
    50 connection = backend.DatabaseWrapper({
    73 # we load all these up for backwards compatibility, you should use
    51     'DATABASE_HOST': settings.DATABASE_HOST,
    74 # connections['default'] instead.
    52     'DATABASE_NAME': settings.DATABASE_NAME,
    75 connection = connections[DEFAULT_DB_ALIAS]
    53     'DATABASE_OPTIONS': settings.DATABASE_OPTIONS,
    76 backend = load_backend(connection.settings_dict['ENGINE'])
    54     'DATABASE_PASSWORD': settings.DATABASE_PASSWORD,
       
    55     'DATABASE_PORT': settings.DATABASE_PORT,
       
    56     'DATABASE_USER': settings.DATABASE_USER,
       
    57     'TIME_ZONE': settings.TIME_ZONE,
       
    58 })
       
    59 DatabaseError = backend.DatabaseError
       
    60 IntegrityError = backend.IntegrityError
       
    61 
    77 
    62 # Register an event that closes the database connection
    78 # Register an event that closes the database connection
    63 # when a Django request is finished.
    79 # when a Django request is finished.
    64 def close_connection(**kwargs):
    80 def close_connection(**kwargs):
    65     connection.close()
    81     for conn in connections.all():
       
    82         conn.close()
    66 signals.request_finished.connect(close_connection)
    83 signals.request_finished.connect(close_connection)
    67 
    84 
    68 # Register an event that resets connection.queries
    85 # Register an event that resets connection.queries
    69 # when a Django request is started.
    86 # when a Django request is started.
    70 def reset_queries(**kwargs):
    87 def reset_queries(**kwargs):
    71     connection.queries = []
    88     for conn in connections.all():
       
    89         conn.queries = []
    72 signals.request_started.connect(reset_queries)
    90 signals.request_started.connect(reset_queries)
    73 
    91 
    74 # Register an event that rolls back the connection
    92 # Register an event that rolls back the connections
    75 # when a Django request has an exception.
    93 # when a Django request has an exception.
    76 def _rollback_on_exception(**kwargs):
    94 def _rollback_on_exception(**kwargs):
    77     from django.db import transaction
    95     from django.db import transaction
    78     try:
    96     for conn in connections:
    79         transaction.rollback_unless_managed()
    97         try:
    80     except DatabaseError:
    98             transaction.rollback_unless_managed(using=conn)
    81         pass
    99         except DatabaseError:
       
   100             pass
    82 signals.got_request_exception.connect(_rollback_on_exception)
   101 signals.got_request_exception.connect(_rollback_on_exception)