On Jul 13, 4:51 pm, Emily Rodgers <
emily.kate.rodg...@googlemail.com>
I finally think I have got this working! I have only tested this using
a script that pokes data into a database using django, not using a web
app (yet), so it may need tweaking in that situation (the signal
stuff), but, hopefully that won't be too much of a problem.
Basically I found an example that kimus.linuxus provided [1] that uses
a later version of django (I am using 1.0.2), and used the ideas from
it to adapt Eric Florenzano's example, and here is what I did:
In my models.py:
from project.app.managers import *
class Db1Model(models.Model):
_default_manager = MultiDBManager('db1')
objects = MultiDBManager('db1')
db = 'db1'
class Meta:
abstract = True
# then for all models that use db1:
class MyModelFromDb1(Db1Model):
...
class Db2Model(models.Model):
_default_manager = MultiDBManager('db2')
objects = MultiDBManager('db2')
db = 'db2'
class Meta:
abstract = True
# ditto for models in db2
class MyModelFromDb2(Db2Model):
...
Then in managers.py:
from django.db import models
from django.conf import settings
from django.db.models import sql
from django.db.transaction import savepoint_state
from django.core import signals
try:
import thread
except ImportError:
import dummy_thread as thread
_connections = {}
def close_connection(**kwargs):
global _connections
for connection in _connections.itervalues():
connection.close()
_connections = {}
signals.request_finished.connect(close_connection)
class MultiDBManager(models.Manager):
def __init__(self, database, *args, **kwargs):
self.database = database
self.use_for_related_fields = True
super(MultiDBManager, self).__init__(*args, **kwargs)
def get_query_set(self):
qs = super(MultiDBManager, self).get_query_set()
qs.query.connection = self.get_db_wrapper()
return qs
def get_db_wrapper(self):
if not self.database:
from django import connection
return connection
if not _connections.has_key(self.database):
settings_dict = settings.DATABASES[self.database]
backend = __import__('django.db.backends.%s.base' %
settings_dict['DATABASE_ENGINE'], {}, {}, ['base'])
backup = {}
for key, value in settings_dict.iteritems():
backup[key] = getattr(settings, key)
setattr(settings, key, value)
wrapper = backend.DatabaseWrapper()
wrapper._cursor(settings)
_connections[self.database] = wrapper
for key, value in backup.iteritems():
setattr(settings, key, value)
return _connections[self.database]
def _insert(self, values, return_id=False, raw_values=False):
query = sql.InsertQuery(self.model, self.get_db_wrapper())
query.insert_values(values, raw_values)
ret = query.execute_sql(return_id)
query.connection._commit()
thread_ident = thread.get_ident()
if thread_ident in savepoint_state:
del savepoint_state[thread_ident]
return ret
Then all you need to do is put the database connection details in
settings.py:
DATABASE_ENGINE = 'mysql'
DATABASE_NAME = 'db1'
DATABASE_USER = 'auser'
DATABASE_PASSWORD = 'somepassword'
DATABASE_HOST = ''
DATABASE_PORT = ''
DATABASES = dict(
db1 = dict(
DATABASE_ENGINE=DATABASE_ENGINE,
DATABASE_NAME=DATABASE_NAME,
DATABASE_USER=DATABASE_USER,
DATABASE_PASSWORD=DATABASE_PASSWORD,
DATABASE_HOST=DATABASE_HOST,
DATABASE_PORT=DATABASE_PORT,
),
db2 = dict(
DATABASE_ENGINE="mysql",
DATABASE_NAME='db2',
DATABASE_USER='anotheruser',
DATABASE_PASSWORD='password',
DATABASE_HOST='',
DATABASE_PORT='',
),
)
It seems to have worked for me so far. Obviously this is not a long
term solution, just something to get by with until Alex's code is
ready =)
Em
[1]
http://code.djangoproject.com/ticket/1142#comment:65
[2]
http://www.eflorenzano.com/blog/post/easy-multi-database-support-django/