先日Laravel案件で、目的によって複数DBを使い分けるシステムを構築したのだが、その時にハマったことなどを備忘録としてまとめておく。
DB接続情報の定義
まず、複数のDBを使用するにあたり、それぞれのDBの接続情報を.env
ファイルに記述する。
※今回は二つのPostgreSQLに接続する例を紹介する。
# デフォルトDB
DB_CONNECTION=db01
DB_HOST=xxx.xxx.xxx.xxx
DB_PORT=xxxx
DB_DATABASE=xxxx
DB_USERNAME=xxxx
DB_PASSWORD=xxxx
# 二つ目のDB
DB_CONNECTION_02=db02
DB_HOST_02=xxx.xxx.xxx.xxx
DB_PORT_02=xxxx
DB_DATABASE_02=xxxx
DB_USERNAME_02=xxxx
DB_PASSWORD_02=xxxx
次にconfig/database.php
のconnections
にも接続情報を追記する。
<?php
use Illuminate\Support\Str;
return [
'default' => env('DB_CONNECTION', 'mysql'),
'connections' => [
// ...
'db01' => [
'driver' => 'pgsql',
'url' => env('DATABASE_URL'),
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '5432'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
'charset' => 'utf8',
'prefix' => '',
'prefix_indexes' => true,
'search_path' => 'public',
'sslmode' => 'prefer',
],
'db02' => [
'driver' => 'pgsql',
'url' => env('DATABASE_URL'),
'host' => env('DB_HOST_02', '127.0.0.1'),
'port' => env('DB_PORT_02', '5432'),
'database' => env('DB_DATABASE_02', 'forge'),
'username' => env('DB_USERNAME_02', 'forge'),
'password' => env('DB_PASSWORD_02', ''),
'charset' => 'utf8',
'prefix' => '',
'prefix_indexes' => true,
'search_path' => 'public',
'sslmode' => 'prefer',
],
],
];
コードを少し解説すると、default
にDB_CONNECTION
が指定されているが、これは.env
ファイルで定義したdb01
をデフォルトの接続先とすることを意味している。
マイグレーション時のDB接続先を変更する
マイグレーションする際、何もしないと前述のdefault
で指定したDBに対して操作がおこなわれてしまうので、接続先を変更するため以下の記述が必要となる。
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
protected $connection = 'db02'; // 追記
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
// ...
これでマイグレーションを実行すると、db02
として定義したDBに対してマイグレーション操作がおこなわれるようになる。
モデルファイルの接続設定
接続先DBが変わるので、当然モデルファイルでも接続設定をおこなわなければならない。
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Product extends Model
{
use HasFactory;
/** @var string DB接続設定 */
protected $connection = 'db02';
// ...
接続設定の書き方はマイグレーションファイルと同様、$connection
で接続先を指定する。
なお注意点として、モデル間でリレーションを取る場合(hasManyなど)にそれぞれのモデルが参照するテーブルが属するDBが異なるとエラーとなってしまうので、モデルの接続設定はデフォルトDBを使う場合でも以下のように接続先を明示しておく必要がある。
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class ProductMaster extends Model
{
use HasFactory;
/** @var string DB接続設定 */
protected $connection = 'db01';
// ...
複数のDBを使用する場合は、とりあえず全モデルファイルで接続設定を記述しておく方が無難だろう。