FuelPHP1.7でORMから複数のDBを使う

複数のDBを使うときに、いちいち

DB::query('SELECT * FROM users')->execute('another_db');

とか書きたくないので、以下のように実装したい。

  • ORMを使う
  • db.phpに複数DBの設定を記述。
  • \Orm\Modelを継承したModelで、接続先を定義

db.phpの実装

defaultのDBの他に"slave"という名前のDB設定を定義する。

return array(
	'default' => array(
		'connection'  => array(
			'dsn'        => 'mysql:host=localhost;dbname=master',
			'username'   => 'username',
			'password'   => 'password',
		),
	),
    'slave' => array(
        'type' => 'pdo',
        'table_prefix' => '',
        'connection'  => array(
            'dsn'        => 'mysql:host=localhost;dbname=slave',
            'username'   => 'username',
            'password'   => 'password',
        ),
    ),
);

'slave'配列の設定を診てもらうと判るのだが、'type'と'table_prefix'を明示的に設定している。これが肝(理由は後述)。

Model側の実装

class Model_Hoge extends \Orm\Model
{
    protected static $_connection = "slave";
    protected static $_properties = array(
        "id",
        "name",
        "created_at",
        "updated_at"
    );
    

    protected static $_observers = array(
		'Orm\Observer_CreatedAt' => array(
			'events' => array('before_insert'),
			'mysql_timestamp' => true,
		),
		'Orm\Observer_UpdatedAt' => array(
			'events' => array('before_save'),
			'mysql_timestamp' => true,
		),
	);
}

$_connectionというstaticプロパティに、"slave"を設定するだけで、このテーブルを参照するときは自動的にslaveのDBへつないでくれる。便利。

注意事項

前述したが"type"と"table_prefix"を明記しないと、以下のようなエラーになる。

Fuel\Core\FuelException [ Error ]:
Database type not defined in "{$name}" configuration or "{$name}" configuration does not exist

該当するソースコードは下記。
COREPATH/classes/database/connection.php

72            if ( ! isset($config['type']))
73            {
74                throw new \FuelException('Database type not defined in "{$name}" configuration or "{$name}" configuration does not exist');
75            }

72行目の$config['type']がセットされていないのでエラーになってしまう。

db.phpの'default'の設定では明記しなくてもエラーにならないので、ここでハマりがち。