mirror of
https://github.com/django/django.git
synced 2025-07-05 18:29:11 +00:00
[soc2009/multidb] Implemented a connections object that is responsible for tracking multiple database connections and lazily instantiating them. Also implemneted the DATABASES setting which replaces the various DATABASE_* settings
git-svn-id: http://code.djangoproject.com/svn/django/branches/soc2009/multidb@10892 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
4cd29f2520
commit
bce55b1aa8
@ -131,6 +131,9 @@ DATABASE_HOST = '' # Set to empty string for localhost. Not used wit
|
|||||||
DATABASE_PORT = '' # Set to empty string for default. Not used with sqlite3.
|
DATABASE_PORT = '' # Set to empty string for default. Not used with sqlite3.
|
||||||
DATABASE_OPTIONS = {} # Set to empty dictionary for default.
|
DATABASE_OPTIONS = {} # Set to empty dictionary for default.
|
||||||
|
|
||||||
|
DATABASES = {
|
||||||
|
}
|
||||||
|
|
||||||
# Host for sending e-mail.
|
# Host for sending e-mail.
|
||||||
EMAIL_HOST = 'localhost'
|
EMAIL_HOST = 'localhost'
|
||||||
|
|
||||||
|
@ -9,12 +9,17 @@ ADMINS = (
|
|||||||
|
|
||||||
MANAGERS = ADMINS
|
MANAGERS = ADMINS
|
||||||
|
|
||||||
DATABASE_ENGINE = '' # 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
|
DATABASES = {
|
||||||
DATABASE_NAME = '' # Or path to database file if using sqlite3.
|
'default': {
|
||||||
DATABASE_USER = '' # Not used with sqlite3.
|
'DATABASE_ENGINE': '', # 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
|
||||||
DATABASE_PASSWORD = '' # Not used with sqlite3.
|
'DATABASE_NAME': '', # Or path to database file if using sqlite3.
|
||||||
DATABASE_HOST = '' # Set to empty string for localhost. Not used with sqlite3.
|
'DATABASE_USER': '', # Not used with sqlite3.
|
||||||
DATABASE_PORT = '' # Set to empty string for default. Not used with sqlite3.
|
'DATABASE_PASSWORD': '', # Not used with sqlite3.
|
||||||
|
'DATABASE_HOST': '', # Set to empty string for localhost. Not used with sqlite3.
|
||||||
|
'DATABASE_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
|
||||||
|
@ -1,14 +1,23 @@
|
|||||||
|
from optparse import make_option
|
||||||
|
|
||||||
from django.core.management.base import LabelCommand
|
from django.core.management.base import LabelCommand
|
||||||
|
from django.db import connections, transaction, models
|
||||||
|
|
||||||
class Command(LabelCommand):
|
class Command(LabelCommand):
|
||||||
help = "Creates the table needed to use the SQL cache backend."
|
help = "Creates the table needed to use the SQL cache backend."
|
||||||
args = "<tablename>"
|
args = "<tablename>"
|
||||||
label = 'tablename'
|
label = 'tablename'
|
||||||
|
|
||||||
|
options_list = LabelCommand.options_list + (
|
||||||
|
make_option('--database', action='store', dest='database',
|
||||||
|
default='default', help='Selects what database to install the cache table to.'),
|
||||||
|
)
|
||||||
|
|
||||||
requires_model_validation = False
|
requires_model_validation = False
|
||||||
|
|
||||||
def handle_label(self, tablename, **options):
|
def handle_label(self, tablename, **options):
|
||||||
from django.db import connection, transaction, models
|
alias = options['alias']
|
||||||
|
connection = connections[alias]
|
||||||
fields = (
|
fields = (
|
||||||
# "key" is a reserved word in MySQL, so use "cache_key" instead.
|
# "key" is a reserved word in MySQL, so use "cache_key" instead.
|
||||||
models.CharField(name='cache_key', max_length=255, unique=True, primary_key=True),
|
models.CharField(name='cache_key', max_length=255, unique=True, primary_key=True),
|
||||||
@ -17,7 +26,7 @@ class Command(LabelCommand):
|
|||||||
)
|
)
|
||||||
table_output = []
|
table_output = []
|
||||||
index_output = []
|
index_output = []
|
||||||
qn = connection.ops.quote_name
|
qn = connections.ops.quote_name
|
||||||
for f in fields:
|
for f in fields:
|
||||||
field_output = [qn(f.name), f.db_type()]
|
field_output = [qn(f.name), f.db_type()]
|
||||||
field_output.append("%sNULL" % (not f.null and "NOT " or ""))
|
field_output.append("%sNULL" % (not f.null and "NOT " or ""))
|
||||||
|
@ -1,44 +1,25 @@
|
|||||||
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.core.exceptions import ImproperlyConfigured
|
||||||
|
from django.db.utils import ConnectionHandler, load_backend
|
||||||
from django.utils.functional import curry
|
from django.utils.functional import curry
|
||||||
from django.utils.importlib import import_module
|
|
||||||
|
|
||||||
__all__ = ('backend', 'connection', 'DatabaseError', 'IntegrityError')
|
__all__ = ('backend', 'connection', 'DatabaseError', 'IntegrityError')
|
||||||
|
|
||||||
if not settings.DATABASE_ENGINE:
|
if not settings.DATABASES or 'default' not in settings.DATABASES:
|
||||||
settings.DATABASE_ENGINE = 'dummy'
|
settings.DATABASES['default'] = {
|
||||||
|
'DATABASE_ENGINE': settings.DATABASE_ENGINE,
|
||||||
|
'DATABASE_HOST': settings.DATABASE_HOST,
|
||||||
|
'DATABASE_NAME': settings.DATABASE_NAME,
|
||||||
|
'DATABASE_OPTIONS': settings.DATABASE_OPTIONS,
|
||||||
|
'DATABASE_PASSWORD': settings.DATABASE_PASSWORD,
|
||||||
|
'DATABASE_PORT': settings.DATABASE_PORT,
|
||||||
|
'DATABASE_USER': settings.DATABASE_USER,
|
||||||
|
'TIME_ZONE': settings.TIME_ZONE,
|
||||||
|
}
|
||||||
|
|
||||||
def load_backend(backend_name):
|
connections = ConnectionHandler(settings.DATABASES)
|
||||||
try:
|
|
||||||
# Most of the time, the database backend will be one of the official
|
|
||||||
# backends that ships with Django, so look there first.
|
|
||||||
return import_module('.base', 'django.db.backends.%s' % backend_name)
|
|
||||||
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:
|
|
||||||
return import_module('.base', backend_name)
|
|
||||||
except ImportError, e_user:
|
|
||||||
# The database backend wasn't found. Display a helpful error message
|
|
||||||
# listing all possible (built-in) database backends.
|
|
||||||
backend_dir = os.path.join(__path__[0], 'backends')
|
|
||||||
try:
|
|
||||||
available_backends = [f for f in os.listdir(backend_dir)
|
|
||||||
if os.path.isdir(os.path.join(backend_dir, f))
|
|
||||||
and not f.startswith('.')]
|
|
||||||
except EnvironmentError:
|
|
||||||
available_backends = []
|
|
||||||
available_backends.sort()
|
|
||||||
if backend_name not in available_backends:
|
|
||||||
error_msg = "%r isn't an available database backend. Available options are: %s\nError was: %s" % \
|
|
||||||
(backend_name, ", ".join(map(repr, available_backends)), e_user)
|
|
||||||
raise ImproperlyConfigured(error_msg)
|
|
||||||
else:
|
|
||||||
raise # If there's some other error, this must be an error in Django itself.
|
|
||||||
|
|
||||||
backend = load_backend(settings.DATABASE_ENGINE)
|
|
||||||
|
|
||||||
# `connection`, `DatabaseError` and `IntegrityError` are convenient aliases
|
# `connection`, `DatabaseError` and `IntegrityError` are convenient aliases
|
||||||
# for backend bits.
|
# for backend bits.
|
||||||
@ -47,15 +28,10 @@ backend = load_backend(settings.DATABASE_ENGINE)
|
|||||||
# we manually create the dictionary from the settings, passing only the
|
# we manually create the dictionary from the settings, passing only the
|
||||||
# settings that the database backends care about. Note that TIME_ZONE is used
|
# settings that the database backends care about. Note that TIME_ZONE is used
|
||||||
# by the PostgreSQL backends.
|
# by the PostgreSQL backends.
|
||||||
connection = backend.DatabaseWrapper({
|
# we load all these up for backwards compatibility, you should use
|
||||||
'DATABASE_HOST': settings.DATABASE_HOST,
|
# connections['default'] instead.
|
||||||
'DATABASE_NAME': settings.DATABASE_NAME,
|
connection = connections['default']
|
||||||
'DATABASE_OPTIONS': settings.DATABASE_OPTIONS,
|
backend = load_backend(settings.DATABASE_ENGINE)
|
||||||
'DATABASE_PASSWORD': settings.DATABASE_PASSWORD,
|
|
||||||
'DATABASE_PORT': settings.DATABASE_PORT,
|
|
||||||
'DATABASE_USER': settings.DATABASE_USER,
|
|
||||||
'TIME_ZONE': settings.TIME_ZONE,
|
|
||||||
})
|
|
||||||
DatabaseError = backend.DatabaseError
|
DatabaseError = backend.DatabaseError
|
||||||
IntegrityError = backend.IntegrityError
|
IntegrityError = backend.IntegrityError
|
||||||
|
|
||||||
|
55
django/db/utils.py
Normal file
55
django/db/utils.py
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
import os
|
||||||
|
|
||||||
|
from django.utils.importlib import import_module
|
||||||
|
|
||||||
|
def load_backend(backend_name):
|
||||||
|
try:
|
||||||
|
# Most of the time, the database backend will be one of the official
|
||||||
|
# backends that ships with Django, so look there first.
|
||||||
|
return import_module('.base', 'django.db.backends.%s' % backend_name)
|
||||||
|
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:
|
||||||
|
return import_module('.base', backend_name)
|
||||||
|
except ImportError, e_user:
|
||||||
|
# The database backend wasn't found. Display a helpful error message
|
||||||
|
# listing all possible (built-in) database backends.
|
||||||
|
backend_dir = os.path.join(__path__[0], 'backends')
|
||||||
|
try:
|
||||||
|
available_backends = [f for f in os.listdir(backend_dir)
|
||||||
|
if os.path.isdir(os.path.join(backend_dir, f))
|
||||||
|
and not f.startswith('.')]
|
||||||
|
except EnvironmentError:
|
||||||
|
available_backends = []
|
||||||
|
available_backends.sort()
|
||||||
|
if backend_name not in available_backends:
|
||||||
|
error_msg = "%r isn't an available database backend. Available options are: %s\nError was: %s" % \
|
||||||
|
(backend_name, ", ".join(map(repr, available_backends)), e_user)
|
||||||
|
raise ImproperlyConfigured(error_msg)
|
||||||
|
else:
|
||||||
|
raise # If there's some other error, this must be an error in Django itself.
|
||||||
|
|
||||||
|
class ConnectionHandler(object):
|
||||||
|
def __init__(self, databases):
|
||||||
|
self.databases = databases
|
||||||
|
self._connections = {}
|
||||||
|
|
||||||
|
def check_connection(self, alias):
|
||||||
|
conn = self.databases[alias]
|
||||||
|
conn.setdefault('DATABASE_ENGINE', 'dummy')
|
||||||
|
conn.setdefault('DATABASE_OPTIONS', {})
|
||||||
|
for setting in ('DATABASE_NAME', 'DATABASE_USER', 'DATABASE_PASSWORD',
|
||||||
|
'DATABASE_HOST', 'DATABASE_PORT'):
|
||||||
|
conn.setdefault(setting, '')
|
||||||
|
|
||||||
|
def __getitem__(self, alias):
|
||||||
|
if alias in self._connections:
|
||||||
|
return self._connections[alias]
|
||||||
|
|
||||||
|
self.check_connection(alias)
|
||||||
|
db = self.databases[alias]
|
||||||
|
backend = load_backend(db['DATABASE_ENGINE'])
|
||||||
|
conn = backend.DatabaseWrapper(db)
|
||||||
|
self._connections[alias] = conn
|
||||||
|
return conn
|
@ -130,8 +130,8 @@ There's also a hook for backend-specific SQL data. For example, you can have
|
|||||||
separate initial-data files for PostgreSQL and MySQL. For each app, Django
|
separate initial-data files for PostgreSQL and MySQL. For each app, Django
|
||||||
looks for a file called ``<appname>/sql/<modelname>.<backend>.sql``, where
|
looks for a file called ``<appname>/sql/<modelname>.<backend>.sql``, where
|
||||||
``<appname>`` is your app directory, ``<modelname>`` is the model's name in
|
``<appname>`` is your app directory, ``<modelname>`` is the model's name in
|
||||||
lowercase and ``<backend>`` is the value of :setting:`DATABASE_ENGINE` in your
|
lowercase and ``<backend>`` is the value of ``DATABASE_ENGINE`` for the given
|
||||||
settings file (e.g., ``postgresql``, ``mysql``).
|
database being set up in your settings file (e.g., ``postgresql``, ``mysql``).
|
||||||
|
|
||||||
Backend-specific SQL data is executed before non-backend-specific SQL data. For
|
Backend-specific SQL data is executed before non-backend-specific SQL data. For
|
||||||
example, if your app contains the files ``sql/person.sql`` and
|
example, if your app contains the files ``sql/person.sql`` and
|
||||||
|
@ -18,15 +18,16 @@ 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 these settings in your
|
what the name of the database is. Do that by editing the :setting:`DATABASES`
|
||||||
:ref:`settings file <topics-settings>`:
|
setting and assigning values to the following keys in the ``'default'``
|
||||||
|
dictionary:
|
||||||
|
|
||||||
* :setting:`DATABASE_NAME`
|
* ``DATABASE_NAME``
|
||||||
* :setting:`DATABASE_ENGINE`
|
* ``DATABASE_ENGINE``
|
||||||
* :setting:`DATABASE_USER`
|
* ``DATABASE_USER``
|
||||||
* :setting:`DATABASE_PASSWORD`
|
* ``DATABASE_PASSWORD``
|
||||||
* :setting:`DATABASE_HOST`
|
* ``DATABASE_HOST``
|
||||||
* :setting:`DATABASE_PORT`
|
* ``DATABASE_PORT``
|
||||||
|
|
||||||
Auto-generate the models
|
Auto-generate the models
|
||||||
========================
|
========================
|
||||||
|
@ -752,20 +752,20 @@ To run the tests, ``cd`` to the ``tests/`` directory and type:
|
|||||||
./runtests.py --settings=path.to.django.settings
|
./runtests.py --settings=path.to.django.settings
|
||||||
|
|
||||||
Yes, the unit tests need a settings module, but only for database connection
|
Yes, the unit tests need a settings module, but only for database connection
|
||||||
info, with the ``DATABASE_ENGINE`` setting.
|
info, with the ``DATABASES`` setting.
|
||||||
|
|
||||||
If you're using the ``sqlite3`` database backend, no further settings are
|
If you're using the ``sqlite3`` database backend, no further settings are
|
||||||
needed. A temporary database will be created in memory when running the tests.
|
needed. A temporary database will be created in memory when running the tests.
|
||||||
|
|
||||||
If you're using another backend:
|
If you're using another backend:
|
||||||
|
|
||||||
* Your :setting:`DATABASE_USER` setting needs to specify an existing user account
|
* Your the ``DATABASE_USER`` option for the ``'default'`` datbase setting
|
||||||
for the database engine.
|
needs to specify an existing user account for the database engine.
|
||||||
|
|
||||||
* The :setting:`DATABASE_NAME` setting must be the name of an existing database to
|
* The ``DATABASE_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
|
``DATABASE_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``.
|
||||||
|
|
||||||
|
@ -42,13 +42,13 @@ code, then run the command ``django-admin.py startproject mysite``. This will
|
|||||||
create a ``mysite`` directory in your current directory.
|
create a ``mysite`` directory in your current directory.
|
||||||
|
|
||||||
.. admonition:: Mac OS X permissions
|
.. admonition:: Mac OS X permissions
|
||||||
|
|
||||||
If you're using Mac OS X, you may see the message "permission denied" when
|
If you're using Mac OS X, you may see the message "permission denied" when
|
||||||
you try to run ``django-admin.py startproject``. This is because, on
|
you try to run ``django-admin.py startproject``. This is because, on
|
||||||
Unix-based systems like OS X, a file must be marked as "executable" before it
|
Unix-based systems like OS X, a file must be marked as "executable" before it
|
||||||
can be run as a program. To do this, open Terminal.app and navigate (using
|
can be run as a program. To do this, open Terminal.app and navigate (using
|
||||||
the ``cd`` command) to the directory where :ref:`django-admin.py
|
the ``cd`` command) to the directory where :ref:`django-admin.py
|
||||||
<ref-django-admin>` is installed, then run the command
|
<ref-django-admin>` is installed, then run the command
|
||||||
``chmod +x django-admin.py``.
|
``chmod +x django-admin.py``.
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
@ -90,14 +90,14 @@ These files are:
|
|||||||
* :file:`__init__.py`: An empty file that tells Python that this directory
|
* :file:`__init__.py`: An empty file that tells Python that this directory
|
||||||
should be considered a Python package. (Read `more about packages`_ in the
|
should be considered a Python package. (Read `more about packages`_ in the
|
||||||
official Python docs if you're a Python beginner.)
|
official Python docs if you're a Python beginner.)
|
||||||
|
|
||||||
* :file:`manage.py`: A command-line utility that lets you interact with this
|
* :file:`manage.py`: A command-line utility that lets you interact with this
|
||||||
Django project in various ways. You can read all the details about
|
Django project in various ways. You can read all the details about
|
||||||
:file:`manage.py` in :ref:`ref-django-admin`.
|
:file:`manage.py` in :ref:`ref-django-admin`.
|
||||||
|
|
||||||
* :file:`settings.py`: Settings/configuration for this Django project.
|
* :file:`settings.py`: Settings/configuration for this Django project.
|
||||||
:ref:`topics-settings` will tell you all about how settings work.
|
:ref:`topics-settings` will tell you all about how settings work.
|
||||||
|
|
||||||
* :file:`urls.py`: The URL declarations for this Django project; a "table of
|
* :file:`urls.py`: The URL declarations for this Django project; a "table of
|
||||||
contents" of your Django-powered site. You can read more about URLs in
|
contents" of your Django-powered site. You can read more about URLs in
|
||||||
:ref:`topics-http-urls`.
|
:ref:`topics-http-urls`.
|
||||||
@ -134,22 +134,22 @@ It worked!
|
|||||||
.. admonition:: Changing the port
|
.. admonition:: Changing the port
|
||||||
|
|
||||||
By default, the :djadmin:`runserver` command starts the development server
|
By default, the :djadmin:`runserver` command starts the development server
|
||||||
on the internal IP at port 8000.
|
on the internal IP at port 8000.
|
||||||
|
|
||||||
If you want to change the server's port, pass
|
If you want to change the server's port, pass
|
||||||
it as a command-line argument. For instance, this command starts the server
|
it as a command-line argument. For instance, this command starts the server
|
||||||
on port 8080:
|
on port 8080:
|
||||||
|
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
|
|
||||||
python manage.py runserver 8080
|
python manage.py runserver 8080
|
||||||
|
|
||||||
If you want to change the server's IP, pass it along with the port. So to
|
If you want to change the server's IP, pass it along with the port. So to
|
||||||
listen on all public IPs (useful if you want to show off your work on other
|
listen on all public IPs (useful if you want to show off your work on other
|
||||||
computers), use:
|
computers), use:
|
||||||
|
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
|
|
||||||
python manage.py runserver 0.0.0.0:8000
|
python manage.py runserver 0.0.0.0:8000
|
||||||
|
|
||||||
Full docs for the development server can be found in the
|
Full docs for the development server can be found in the
|
||||||
@ -159,32 +159,33 @@ 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 module-level
|
||||||
variables representing Django settings. Change these settings to match your
|
variables representing Django settings. Change the following keys in the
|
||||||
database's connection parameters:
|
:setting:`DATABASES` ``'default'`` item to match your databases connection
|
||||||
|
settings.
|
||||||
|
|
||||||
* :setting:`DATABASE_ENGINE` -- Either 'postgresql_psycopg2', 'mysql' or
|
* ``DATABASE_ENGINE`` -- Either 'postgresql_psycopg2', 'mysql' or
|
||||||
'sqlite3'. Other backends are :setting:`also available <DATABASE_ENGINE>`.
|
'sqlite3'. Other backends are :setting:`also available <DATABASE_ENGINE>`.
|
||||||
|
|
||||||
* :setting:`DATABASE_NAME` -- The name of your database. If you're using
|
* ``DATABASE_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 case,
|
||||||
``DATABASE_NAME`` should be the full absolute path, including filename, of
|
``DATABASE_NAME`` should be the full absolute path, including filename, of
|
||||||
that file. If the file doesn't exist, it will automatically be created
|
that file. If the file doesn't exist, it will automatically be created
|
||||||
when you synchronize the database for the first time (see below).
|
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 Windows
|
||||||
(e.g. ``C:/homes/user/mysite/sqlite3.db``).
|
(e.g. ``C:/homes/user/mysite/sqlite3.db``).
|
||||||
|
|
||||||
* :setting:`DATABASE_USER` -- Your database username (not used for SQLite).
|
* ``DATABASE_USER`` -- Your database username (not used for SQLite).
|
||||||
|
|
||||||
* :setting:`DATABASE_PASSWORD` -- Your database password (not used for
|
* ``DATABASE_PASSWORD`` -- Your database password (not used for
|
||||||
SQLite).
|
SQLite).
|
||||||
|
|
||||||
* :setting:`DATABASE_HOST` -- The host your database is on. Leave this as an
|
* ``DATABASE_HOST`` -- The host your database is on. Leave this as an
|
||||||
empty string if your database server is on the same physical machine (not
|
empty string if your database server is on the same physical machine (not
|
||||||
used for SQLite).
|
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 setting
|
||||||
:setting:`DATABASE_ENGINE` to ``'sqlite3'``). SQLite is included as part of
|
``DATABASE_ENGINE`` to ``'sqlite3'``). SQLite is included as part of
|
||||||
Python 2.5 and later, so you won't need to install anything else.
|
Python 2.5 and later, so you won't need to install anything else.
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
@ -594,7 +595,7 @@ your models, not only for your own sanity when dealing with the interactive
|
|||||||
prompt, but also because objects' representations are used throughout Django's
|
prompt, but also because objects' representations are used throughout Django's
|
||||||
automatically-generated admin.
|
automatically-generated admin.
|
||||||
|
|
||||||
.. admonition:: Why :meth:`~django.db.models.Model.__unicode__` and not
|
.. admonition:: Why :meth:`~django.db.models.Model.__unicode__` and not
|
||||||
:meth:`~django.db.models.Model.__str__`?
|
:meth:`~django.db.models.Model.__str__`?
|
||||||
|
|
||||||
If you're familiar with Python, you might be in the habit of adding
|
If you're familiar with Python, you might be in the habit of adding
|
||||||
|
@ -53,7 +53,7 @@ transaction, rather than having the transaction extend over multiple
|
|||||||
operations. In this case, you can still manually start a transaction if you're
|
operations. In this case, you can still manually start a transaction if you're
|
||||||
doing something that requires consistency across multiple database operations.
|
doing something that requires consistency across multiple database operations.
|
||||||
The autocommit behavior is enabled by setting the ``autocommit`` key in the
|
The autocommit behavior is enabled by setting the ``autocommit`` key in the
|
||||||
:setting:`DATABASE_OPTIONS` setting::
|
``DATABASE_OPTIONS`` part of your database in :setting:`DATABASES`::
|
||||||
|
|
||||||
DATABASE_OPTIONS = {
|
DATABASE_OPTIONS = {
|
||||||
"autocommit": True,
|
"autocommit": True,
|
||||||
@ -69,9 +69,9 @@ objects are changed or none of them are.
|
|||||||
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 is a
|
||||||
Django-level implementation that commits automatically after data changing
|
Django-level implementation that commits automatically after data changing
|
||||||
operations. The feature enabled using the :setting:`DATABASE_OPTIONS`
|
operations. The feature enabled using the ``DATABASE_OPTIONS`` option
|
||||||
settings provides autocommit behavior at the database adapter level. It
|
provides autocommit behavior at the database adapter level. It commits
|
||||||
commits after *every* operation.
|
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,10 +234,10 @@ Refer to the :ref:`settings documentation <ref-settings>`.
|
|||||||
|
|
||||||
Connection settings are used in this order:
|
Connection settings are used in this order:
|
||||||
|
|
||||||
1. :setting:`DATABASE_OPTIONS`.
|
1. ``DATABASE_OPTIONS``.
|
||||||
2. :setting:`DATABASE_NAME`, :setting:`DATABASE_USER`,
|
2. ``DATABASE_NAME``, ``DATABASE_USER``,
|
||||||
:setting:`DATABASE_PASSWORD`, :setting:`DATABASE_HOST`,
|
``DATABASE_PASSWORD``, ``DATABASE_HOST``,
|
||||||
:setting:`DATABASE_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 ``DATABASE_OPTIONS``,
|
||||||
@ -247,11 +247,16 @@ 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::
|
||||||
|
|
||||||
# settings.py
|
# settings.py
|
||||||
DATABASE_ENGINE = "mysql"
|
DATABASES = {
|
||||||
DATABASE_OPTIONS = {
|
'default': {
|
||||||
'read_default_file': '/path/to/my.cnf',
|
'DATABASE_ENGINE': "mysql",
|
||||||
|
'DATABASE_OPTIONS': {
|
||||||
|
'read_default_file': '/path/to/my.cnf',
|
||||||
|
},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
# my.cnf
|
# my.cnf
|
||||||
[client]
|
[client]
|
||||||
database = DATABASE_NAME
|
database = DATABASE_NAME
|
||||||
@ -445,10 +450,10 @@ If you're getting this error, you can solve it by:
|
|||||||
* Switching to another database backend. At a certain point SQLite becomes
|
* Switching to another database backend. At a certain point SQLite becomes
|
||||||
too "lite" for real-world applications, and these sorts of concurrency
|
too "lite" for real-world applications, and these sorts of concurrency
|
||||||
errors indicate you've reached that point.
|
errors indicate you've reached that point.
|
||||||
|
|
||||||
* Rewriting your code to reduce concurrency and ensure that database
|
* Rewriting your code to reduce concurrency and ensure that database
|
||||||
transactions are short-lived.
|
transactions are short-lived.
|
||||||
|
|
||||||
* Increase the default timeout value by setting the ``timeout`` database
|
* Increase the default timeout value by setting the ``timeout`` database
|
||||||
option option::
|
option option::
|
||||||
|
|
||||||
@ -457,7 +462,7 @@ If you're getting this error, you can solve it by:
|
|||||||
"timeout": 20,
|
"timeout": 20,
|
||||||
# ...
|
# ...
|
||||||
}
|
}
|
||||||
|
|
||||||
This will simply make SQLite wait a bit longer before throwing "database
|
This will simply make SQLite wait a bit longer before throwing "database
|
||||||
is locked" errors; it won't really do anything to solve them.
|
is locked" errors; it won't really do anything to solve them.
|
||||||
|
|
||||||
@ -501,25 +506,34 @@ Connecting to the database
|
|||||||
|
|
||||||
Your Django settings.py file should look something like this for Oracle::
|
Your Django settings.py file should look something like this for Oracle::
|
||||||
|
|
||||||
DATABASE_ENGINE = 'oracle'
|
DATABASES = {
|
||||||
DATABASE_NAME = 'xe'
|
'default': {
|
||||||
DATABASE_USER = 'a_user'
|
'DATABASE_ENGINE': 'oracle',
|
||||||
DATABASE_PASSWORD = 'a_password'
|
'DATABASE_NAME': 'xe',
|
||||||
DATABASE_HOST = ''
|
'DATABASE_USER': 'a_user',
|
||||||
DATABASE_PORT = ''
|
'DATABASE_PASSWORD': 'a_password',
|
||||||
|
'DATABASE_HOST': '',
|
||||||
|
'DATABASE_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
|
||||||
:setting:`DATABASE_HOST` and :setting:`DATABASE_PORT` like so::
|
``DATABASE_HOST`` and ``DATABASE_PORT`` like so::
|
||||||
|
|
||||||
DATABASE_ENGINE = 'oracle'
|
DATABASES = {
|
||||||
DATABASE_NAME = 'xe'
|
'default': {
|
||||||
DATABASE_USER = 'a_user'
|
'DATABASE_ENGINE': 'oracle',
|
||||||
DATABASE_PASSWORD = 'a_password'
|
'DATABASE_NAME': 'xe',
|
||||||
DATABASE_HOST = 'dbprod01ned.mycompany.com'
|
'DATABASE_USER': 'a_user',
|
||||||
DATABASE_PORT = '1540'
|
'DATABASE_PASSWORD': 'a_password',
|
||||||
|
'DATABASE_HOST': 'dbprod01ned.mycompany.com',
|
||||||
|
'DATABASE_PORT': '1540',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
You should supply both :setting:`DATABASE_HOST` and :setting:`DATABASE_PORT`, or leave both
|
You should supply both ``DATABASE_HOST`` and ``DATABASE_PORT``, or leave both
|
||||||
as empty strings.
|
as empty strings.
|
||||||
|
|
||||||
Tablespace options
|
Tablespace options
|
||||||
|
@ -144,10 +144,20 @@ Default: ``600``
|
|||||||
The default number of seconds to cache a page when the caching middleware or
|
The default number of seconds to cache a page when the caching middleware or
|
||||||
``cache_page()`` decorator is used.
|
``cache_page()`` decorator is used.
|
||||||
|
|
||||||
.. setting:: DATABASE_ENGINE
|
.. setting:: DATABASES
|
||||||
|
|
||||||
|
DATABASES
|
||||||
|
---------
|
||||||
|
|
||||||
|
Default: ``{}`` (Empty dictionary)
|
||||||
|
|
||||||
|
This is a dictionary containg the settings for all databases to be used with
|
||||||
|
Django. It is a nested dictionary who's contents maps aliases to a dictionary
|
||||||
|
containing the options for an individual database. The following inner options
|
||||||
|
are used:
|
||||||
|
|
||||||
DATABASE_ENGINE
|
DATABASE_ENGINE
|
||||||
---------------
|
~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
Default: ``''`` (Empty string)
|
Default: ``''`` (Empty string)
|
||||||
|
|
||||||
@ -164,10 +174,8 @@ examples.
|
|||||||
.. versionadded:: 1.0
|
.. versionadded:: 1.0
|
||||||
Support for external database backends is new in 1.0.
|
Support for external database backends is new in 1.0.
|
||||||
|
|
||||||
.. setting:: DATABASE_HOST
|
|
||||||
|
|
||||||
DATABASE_HOST
|
DATABASE_HOST
|
||||||
-------------
|
~~~~~~~~~~~~~
|
||||||
|
|
||||||
Default: ``''`` (Empty string)
|
Default: ``''`` (Empty string)
|
||||||
|
|
||||||
@ -177,7 +185,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'
|
"DATABASE_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.
|
||||||
@ -187,50 +195,40 @@ 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.
|
||||||
|
|
||||||
.. setting:: DATABASE_NAME
|
|
||||||
|
|
||||||
DATABASE_NAME
|
DATABASE_NAME
|
||||||
-------------
|
~~~~~~~~~~~~~
|
||||||
|
|
||||||
Default: ``''`` (Empty string)
|
Default: ``''`` (Empty string)
|
||||||
|
|
||||||
The name of the database to use. For SQLite, it's the full path to the database
|
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``).
|
||||||
|
|
||||||
.. setting:: DATABASE_OPTIONS
|
|
||||||
|
|
||||||
DATABASE_OPTIONS
|
DATABASE_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.
|
||||||
|
|
||||||
.. setting:: DATABASE_PASSWORD
|
|
||||||
|
|
||||||
DATABASE_PASSWORD
|
DATABASE_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.
|
||||||
|
|
||||||
.. setting:: DATABASE_PORT
|
|
||||||
|
|
||||||
DATABASE_PORT
|
DATABASE_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.
|
||||||
|
|
||||||
.. setting:: DATABASE_USER
|
|
||||||
|
|
||||||
DATABASE_USER
|
DATABASE_USER
|
||||||
-------------
|
~~~~~~~~~~~~~
|
||||||
|
|
||||||
Default: ``''`` (Empty string)
|
Default: ``''`` (Empty string)
|
||||||
|
|
||||||
@ -251,7 +249,7 @@ See also ``DATETIME_FORMAT``, ``TIME_FORMAT``, ``YEAR_MONTH_FORMAT``
|
|||||||
and ``MONTH_DAY_FORMAT``.
|
and ``MONTH_DAY_FORMAT``.
|
||||||
|
|
||||||
.. setting:: DATETIME_FORMAT
|
.. setting:: DATETIME_FORMAT
|
||||||
|
|
||||||
DATETIME_FORMAT
|
DATETIME_FORMAT
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
@ -519,14 +517,14 @@ system's standard umask.
|
|||||||
.. warning::
|
.. warning::
|
||||||
|
|
||||||
**Always prefix the mode with a 0.**
|
**Always prefix the mode with a 0.**
|
||||||
|
|
||||||
If you're not familiar with file modes, please note that the leading
|
If you're not familiar with file modes, please note that the leading
|
||||||
``0`` is very important: it indicates an octal number, which is the
|
``0`` is very important: it indicates an octal number, which is the
|
||||||
way that modes must be specified. If you try to use ``644``, you'll
|
way that modes must be specified. If you try to use ``644``, you'll
|
||||||
get totally incorrect behavior.
|
get totally incorrect behavior.
|
||||||
|
|
||||||
|
|
||||||
.. _documentation for os.chmod: http://docs.python.org/lib/os-file-dir.html
|
|
||||||
|
.. _documentation for os.chmod: http://docs.python.org/lib/os-file-dir.html
|
||||||
|
|
||||||
.. setting:: FIXTURE_DIRS
|
.. setting:: FIXTURE_DIRS
|
||||||
|
|
||||||
@ -1153,7 +1151,7 @@ running in the correct environment.
|
|||||||
Django cannot reliably use alternate time zones in a Windows environment.
|
Django cannot reliably use alternate time zones in a Windows environment.
|
||||||
If you're running Django on Windows, this variable must be set to match the
|
If you're running Django on Windows, this variable must be set to match the
|
||||||
system timezone.
|
system timezone.
|
||||||
|
|
||||||
.. _See available choices: http://www.postgresql.org/docs/8.1/static/datetime-keywords.html#DATETIME-TIMEZONE-SET-TABLE
|
.. _See available choices: http://www.postgresql.org/docs/8.1/static/datetime-keywords.html#DATETIME-TIMEZONE-SET-TABLE
|
||||||
|
|
||||||
.. setting:: URL_VALIDATOR_USER_AGENT
|
.. setting:: URL_VALIDATOR_USER_AGENT
|
||||||
|
@ -139,8 +139,8 @@ In the case of model tests, note that the test runner takes care of creating
|
|||||||
its own test database. That is, any test that accesses a database -- by
|
its own test database. That is, any test that accesses a database -- by
|
||||||
creating and saving model instances, for example -- will not affect your
|
creating and saving model instances, for example -- will not affect your
|
||||||
production database. However, the database is not refreshed between doctests,
|
production database. However, the database is not refreshed between doctests,
|
||||||
so if your doctest requires a certain state you should consider flushin the
|
so if your doctest requires a certain state you should consider flushin the
|
||||||
database or loading a fixture. (See the section on fixtures, below, for more
|
database or loading a fixture. (See the section on fixtures, below, for more
|
||||||
on this.) Note that to use this feature, the database user Django is connecting
|
on this.) Note that to use this feature, the database user Django is connecting
|
||||||
as must have ``CREATE DATABASE`` rights.
|
as must have ``CREATE DATABASE`` rights.
|
||||||
|
|
||||||
@ -284,7 +284,7 @@ Regardless of whether the tests pass or fail, the test database is 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 this test database gets its name by prepending ``test_`` to the
|
||||||
value of the :setting:`DATABASE_NAME` setting. When using the SQLite database
|
value of the ``DATABASE_NAME`` setting. When using the SQLite database
|
||||||
engine the tests will by default use an in-memory database (i.e., the database
|
engine the tests will by default use an in-memory database (i.e., the database
|
||||||
will be created in memory, bypassing the filesystem entirely!). If you want to
|
will be created in memory, bypassing the filesystem entirely!). If you want to
|
||||||
use a different database name, specify the :setting:`TEST_DATABASE_NAME`
|
use a different database name, specify the :setting:`TEST_DATABASE_NAME`
|
||||||
@ -292,9 +292,9 @@ setting.
|
|||||||
|
|
||||||
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 use all of
|
||||||
the same database settings you have in your settings file:
|
the same database settings you have in your settings file:
|
||||||
:setting:`DATABASE_ENGINE`, :setting:`DATABASE_USER`, :setting:`DATABASE_HOST`,
|
``DATABASE_ENGINE``, ``DATABASE_USER``, ``DATABASE_HOST``,
|
||||||
etc. The test database is created by the user specified by
|
etc. The test database is created by the user specified by
|
||||||
:setting:`DATABASE_USER`, so you'll need to make sure that the given user
|
``DATABASE_USER``, so you'll need to make sure that the given user
|
||||||
account has sufficient privileges to create a new database on the system.
|
account has sufficient privileges to create a new database on the system.
|
||||||
|
|
||||||
.. versionadded:: 1.0
|
.. versionadded:: 1.0
|
||||||
|
0
tests/regressiontests/multiple_database/__init__.py
Normal file
0
tests/regressiontests/multiple_database/__init__.py
Normal file
1
tests/regressiontests/multiple_database/models.py
Normal file
1
tests/regressiontests/multiple_database/models.py
Normal file
@ -0,0 +1 @@
|
|||||||
|
|
17
tests/regressiontests/multiple_database/tests.py
Normal file
17
tests/regressiontests/multiple_database/tests.py
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
from django.conf import settings
|
||||||
|
from django.db import connections
|
||||||
|
from django.test import TestCase
|
||||||
|
|
||||||
|
class DatabaseSettingTestCase(TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
settings.DATABASES['__test_db'] = {
|
||||||
|
'DATABASE_ENGINE': 'sqlite3',
|
||||||
|
'DATABASE_NAME': ':memory:',
|
||||||
|
}
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
del settings.DATABASES['__test_db']
|
||||||
|
|
||||||
|
def test_db_connection(self):
|
||||||
|
connections['default'].cursor()
|
||||||
|
connections['__test_db'].cursor()
|
Loading…
x
Reference in New Issue
Block a user