Login

Manager for multiple database connections

Author:
rix
Posted:
August 6, 2009
Language:
Python
Version:
1.1
Tags:
multiple manager database connection databases connections
Score:
0 (after 2 ratings)

A Django model manager capable of using different database connections.

Inspired by:

There's a more detailed version in Portuguese in my blog: Manager para diferentes conexões de banco no Django

 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
# -*- coding: utf-8 -*-

"""
Sample settings:

DATABASE_ENGINE = 'postgresql_psycopg2'
DATABASE_NAME = 'default_db_name'
DATABASE_USER = 'user'
DATABASE_PASSWORD = ''
DATABASE_HOST = ''
DATABASE_PORT = ''

# Any omitted property will inherit the default value from settings
DATABASES = {
    'default': {},
    'alternative': {
        'DATABASE_NAME': 'alternative_db_name',
    },
}
"""

from django.conf import settings
from django.db import models, backend

# Default connection
db_settings = {
    '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 prepare_db_settings(db_profile_name):
    """
    Takes custom database settings, replaces missing values with the
    defaults from settings and returns a new connection dict.
    """
    return dict(db_settings, **settings.DATABASES[db_profile_name])

class MultiDBManager(models.Manager):
    """
    A manager that can connect to different databases.
    """
    def use(self, db_profile_name):
    	"""
    	Return a queryset connected to a custom database.
    	"""
        # Get customized database settings to use in a new connection wrapper
        db_settings = prepare_db_settings(db_profile_name)

    	# Get the queryset and replace its connection
        qs = self.get_query_set()
        qs.query.connection = backend.DatabaseWrapper(db_settings)
        return qs

More like this

Comments

piratus (on August 7, 2009):
<p>I didn't test, but it seems that this manager has the same problem as the one described by Eric - the connections to the alternative databases are not closed which leads to MySQL errors after some time.</p>

#

rix (on August 7, 2009):
<p>You may be right piratus, I don't know the default Django behaviour to close connections.</p> <p>As we're using an alternative connection, Django may not be aware of it and will leave it open.</p> <p>I'll try to fix this as soon as possible.</p> <p>Thanks for commenting.</p>

#

Please login first before commenting.