summaryrefslogtreecommitdiff
path: root/docs/multiple_database_support.txt
blob: 9b2e037230f6e420efb510f804977263e19a1159 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
========================
Using Multiple Databases
========================

Standard Django practice is to use a single database connection for
all models in all applications. However, Django supports configuring
and using multiple database connections on a per-application, per-model
or an ad-hoc basis. Using multiple database connections is optional.

Configuring other database connections
======================================

Django's default database connection is configured via the settings
DATABASE_ENGINE, DATABASE_NAME, DATABASE_USER, DATABASE_PASSWORD,
DATABASE_HOST, and DATABASE_PORT. Other connections are configured via
the OTHER_DATABASES setting. Define OTHER_DATABASES as a dict, with a
name for each connection as the key and a dict of settings as the
value. In each OTHER_DATABASES entry (called a "named connection"),
the keys are the same as the DATABASE_ENGINE, etc, settings used to
configure the default connection. All keys are optional; any that are
missing in a named connection's settings will inherit their values
from the default connection.

Here's an example::

    DATABASE_ENGINE = 'postgresql'
    DATABASE_NAME = 'django_apps'
    DATABASE_USER = 'default_user'
    DATABASE_PASSWORD = 'xxx'
	
    OTHER_DATABASES = {
        'local': { 'DATABASE_ENGINE': 'sqlite3',
                   'DATABASE_NAME': '/tmp/cache.db' },
        'public': { 'DATABASE_HOST': 'public',
                    'DATABASE_USER': 'public_user',
                    'DATABASE_PASSWORD': 'xxx' }
        'private': { 'DATABASE_HOST': 'private',
                     'DATABASE_USER': 'private_user',
                     'DATABASE_PASSWORD': 'xxx' }
    }

In addition to the DATABASE_* settings, each named connection in
OTHER_DATABASES may optionally include a MODELS setting. This should
be a list of app or app.model names, and is used to configure which
models should use this connection instead of the default connection.

Here's the example above, with ``MODELS``::

    OTHER_DATABASES = {
        'local': { 'DATABASE_ENGINE': 'sqlite3',
                   'DATABASE_NAME': '/tmp/cache.db',
                   # A model name: only the model ContentItem
                   # with the app_label myapp will use this connection
                   'MODELS': ['myapp.ContentItem'] },
        'public': { 'DATABASE_HOST': 'public',
                    'DATABASE_USER': 'public_user',
                    'DATABASE_PASSWORD': 'xxx',
	            # Two models in myapp will use the connection
                    # named 'public', as will ALL models in 
                    # django.contribe.comments
		    'MODELS': ['myapp.Blog','myapp.Article',
                               'django.contrib.comments' ] }
        # No models or apps are configured to use the private db
        'private': { 'DATABASE_HOST': 'private',
                     'DATABASE_USER': 'private_user',
                     'DATABASE_PASSWORD': 'xxx' }
    }

Accessing a model's connection
==============================

Each manager has a ``db`` attribute that can be used to access the model's
connection. Access the ``db`` attribute of a model's manager to obtain the
model's currently configured connection. 

Example::

    from django.db import models

    class Blog(models.Model)
        name = models.CharField(maxlength=50)

    class Article(models.Model)
	blog = models.ForeignKey(Blog)
        title = models.CharField(maxlength=100)
        slug = models.SlugField()
        summary = models.CharField(maxlength=500)
        body = models.TextField()

    class ContentItem(models.Model)
        slug = models.SlugField()
        mimetype = models.CharField(maxlength=50)
	file = models.FileField()
	
    # Get a ConnectionInfo instance that describes the connection
    article_db = Article.objects.db
    
    # Get a connection and a cursor
    connection = article_db.connection
    cursor = connection.cursor()

    # Get the ``quote_name`` function from the backend
    qn = article_db.backend.quote_name

Ordinarily you won't have to access a model's connection directly;
just use the model and manager normally and they will use the
connection configured for the model.

ConnectionInfo objects
======================

FIXME Describe the ConnectionInfo object and each of its attributes.


Accessing connections by name
=============================

Access named connections directly through
``django.db.connections``. Each entry in ``django.db.connections`` is
a ``ConnectionInfo`` instance bound to the settings configured in the
OTHER_DATABASES entry under the same key. 

Example::

    from django.db import connections

    private_db = connections['private']
    cursor = private_db.connection.cursor()


Using transactions with other database connections
==================================================

Transaction managed state applies across all connections
commit/rollback apply to all connections by default
but you can specify individual connections or lists or dicts of connections


Changing model connections on the fly
=====================================

Here's an example of primitive mirroring::
 
    # Read all articles from the private db
    # Note that we pull the articles into a list; this is necessary
    # because query sets are lazy. If we were to change the model's
    # connection without copying the articles into a local list, we'd
    # wind up reading from public instead of private.

    Article.objects.db = connections['private']
    all_articles = list(Article.objects.all())
    
    # Save each article in the public db
    Article.objects.db = connections['public']
    for article in all_articles:
        article.save()

Thread and request isolation
============================

connections close after each request
connection settings are thread-local