Djangoで複数DBを取り扱うためのメモ
移転しました。
以下方法は自分では試してないが、メモとして残しておく。暫定での対応らしい。
Django本体での複数DB対応は■Alexさん■ががんばっているようだ。まだ完成していないもよう。
原文はこちら。
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): ...
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
settings.py:
DBコネクションの設定
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 =) 訳:Alexががんばっているので、それまでの暫定コードです。
以下のページも見ると、参考になる。
[1] http://code.djangoproject.com/ticket/1142#comment:65
[2] http://www.eflorenzano.com/blog/post/easy-multi-database-support-django/