symfonyで動的にDBを切り替える方法
あるデータは、現在使っているのとは別のデータベースに入れたいなぁ。
という時に便利なハックです。
DBの設定追加
databases.ymlにdatabase1用の設定(doctrine)が既にあるとして、新たにdatabase2用の設定を追加します。
all: doctrine: class: sfDoctrineDatabase param: dsn: 'mysql:host=localhost;dbname=database1' username: hoge password: huga database2: class: sfDoctrineDatabase param: dsn: 'mysql:host=localhost;dbname=database2' username: hoge password: huga
デフォルトのコネクション設定
例は、デフォルトをdoctrineにしたい場合です。
<?php // apps/frontend/config/frontendConfiguration.class.php class frontendConfiguration extends sfApplicationConfiguration { public function initialize() { // load symfony autoloading first parent::initialize(); // context.load_factoriesイベントが発火したら、下で定義するsetCurrentConnection()関数を // 呼ぶよう設定。Doctrineの初期化が終わった後に呼ばれるconfigureDoctrine()関数があるけれど、 // この時点ではDBとのコネクション用設定ファイル(databases.yml)が読み込まれていないので、 // この方法を取っている。 // If load_factries event fire, call $this->setCurrentConnection() method. // When configureDoctrine() method is called, configuration file is not loaded yet // for the connection establishment. $this->getEventDispatcher() ->connect('context.load_factories', array($this, 'setCurrentConnection')); } public function configure() { } /** * Set default connection */ public function setCurrentConnection(sfEvent $event) { Doctrine_Manager::getInstance()->setCurrentConnection('doctrine'); } }
別のデータベースへの繋ぎ方
いろいろ操作して、最後 save を呼ぶときに
save(Doctrine_Manager::getInstance()->getConnection('database2'));
と、繋ぎたいDBの名前のコネクション取得して、渡すだけです。
複数の操作がある場合は、
Doctrine_Manager::getInstance()->setCurrentConnection('database2');
で、一時的にコネクション先を変えるのもありです。
戻し忘れに注意
Taskの場合
タスクは、context.load_factoriesイベント取れなかったので、TasknameTask.class.phpのexecute内に
Doctrine_Manager::getInstance()->setCurrentConnection('database2');
を追加してあげてください。