27

現在、CodeIgniter で記述された複数のテナントをホストするアプリケーションがあります。しかし、私は Laravel 4 が大好きで、アプリケーションを Laravel に移行したいと考えています。

現在の設定は次のとおりです。

  • 各テナントには独自のデータベースがあります。
  • アプリケーション ファイルのセットは 1 つだけです。
  • 新しいテナントを作成すると、新しいデータベースが作成され、インストール スクリプトが実行され、データベースに初期情報がシードされます。
  • 各テナントには独自のサブドメインもあります。これが、使用するデータベースを検出する方法です。
  • テナント情報とユーザー、およびその他の一般的なテーブルを保持するメイン データベースがあります。
  • スキーマの更新が必要な場合は、テナントごとに実行される更新スクリプトを作成するだけです。これは、Codeigniter 用に特別にコーディングされた CLI スクリプトを介して行われます。

Codeigniter では、新しいデータベース接続を開始および終了するのは比較的簡単です。

Laravelには、次の問題/質問があります。

  • その場でデータベース接続をどのように開始/終了しますか?
  • 移行を使用したいのですが、テナントごとに実行したいと考えています。移行は現在、「メイン」データベース接続でのみ実行されます。そして、それは一度だけ実行されます。
  • 種まきも同じです..

これらは私の主な問題です。他にもいくつかの小さな問題がありますが、それらは回避できます。

うまくいけば、誰かが光を当てることができます..

4

5 に答える 5

23

私はこれを突き刺しているだけなので、注意してください:) DBを呼び出すたびに使用されるDatabaseManagerクラスには、メソッドがあり、拡張されています。ソースへのリンクは次のとおりです。DB :: connection()メソッドは、Illuminate \ Database\Connectionのインスタンスを返す必要があります。これらすべてから、次のように新しいユーザー接続を作成します。

$user = Auth::user();
DB::extend($user->username, function() use ($user) {
   // $pdo = new PDO(); set this up how you see fit
    return new Illuminate\Database\Connection($pdo, $user->databaseName, $tablePrefix);
});

個人的には、各ユーザーに新しいメソッドUser :: databaseConnection()を追加し、DatabaseManagerを拡張するときにそれを呼び出します。

DB::extend($user->username, function() use ($user) {
    return $user->databaseConnection();
});

アプリケーション全体で、以下を介して登録ユーザーの接続を呼び出すことができるはずです。

DB::connection(Auth::user()->username);

アップデート

テナント接続を呼び出す頻度とタイミングによっては、IOCコンテナを使用することをお勧めします。

App::bind('tenantDB', function()
{
     return DB::connection(Auth::user()->username);
});

App::make('tenantDB')->insert(...);

移行とシードを忘れました。移行の場合、ファイルパスを設定できます

php artisan migrate:make foo --path=app/migrations

したがって、Configクラスを使用してデフォルトのデータベースまたはDB :: setDefaultConnection($ username)を設定する場合、すべての移行とシードは現在の接続に対して行われると想定します。そのプロセスが完了したら、メインデータベースに戻すことができます。

アップデート2

Laravelの開発者は素晴らしく、私は間違いなくこれをもっと早くチェックしたいという衝動に駆られるべきでした。作成した任意のデータベース接続で移行とシードを実行できます。

artisan migrate --database='userConnectionName' 
artisan db:seed --database='userConnectionName'

バリーの答えを見ると、それはおそらくDatabaseManagerを拡張するよりもかなり簡単です。

これらのコマンドのすべてのオプションを確認するには、次のコマンドを実行します。

artisan help migrate
artisan help db:seed
于 2013-01-25T16:09:58.150 に答える
6

テナント データベースの資格情報を使用して 1 つのデータベースを作成し、それらをアプリで動的に設定できます。

$tenant = Tenant::where('username', '=', $username)->first();
Config::set('database.connections.tenant.username', $tenant->db_username);
Config::set('database.connections.tenant.password', $tenant->db_password);
Config::set('database.connections.tenant.database', $tenant->db_database);

これには、database.php ファイルに 2 つの接続を作成する必要があります。(たとえば、アプリとテナント)、使用するデータベースをモデルで指定します (テナントの保存用に 1 つ、テナント固有のデータベース用に 1 つ)。

そしておそらく、テーブルを作成/更新するためのルート/スクリプトを作成します。複数のデータベースを使用した移行については不明です。

于 2013-01-25T16:46:14.263 に答える
4

次の構文を使用して、laravel で動的 DB 接続を作成できます。

Config::set('database.connections.key', array(
    'driver'    => 'mysql',
    'host'      => 'localhost',
    'database'  => 'dbname',
    'username'  => 'dbuser',
    'password'  => 'dbpass',
    'charset'   => 'utf8',
    'collation' => 'utf8_unicode_ci',
    'prefix'    => '',
));

それとDB::connection('key'); would just work.

于 2014-01-04T05:31:31.170 に答える
0

最近、同様の問題に遭遇し、いくつかのモデルに異なるデータベースを使用する必要がありました。

私はトリックを行うために以下を見つけました。

  1. app/config/database.php で、新しい接続 MY_NEW_CONNECTION を追加します
  2. 新しい接続では、データベース名を任意の名前に設定します
  3. あなたのfilters.phpまたはroutes.phpまたはコントローラの__constructメソッドに以下を追加してください:

    $db = 'データベース名を取得'; Config::set('database.connections.MY_NEW_CONNECTION.database',$db); DB::setDefaultConnection('MY_NEW_CONNECTION');

于 2014-11-13T20:22:09.350 に答える
-3

1)database.php構成ファイルで複数の名前付き接続を定義できます

'connections' => array(
    'tenant1' => array(
     ...
    ),
    'tenant2' => array(
     ...
    ),

次に、このようなもので使用するものを選択できます。

$something = DB::connection('tenant1')->select(...);

2)コアでのハッキングが必要になると思うので、これは完全なソリューションではありませんが、移行を実行する接続を選択できます。テナントのリストを繰り返し処理して、すべてのテナントで実行できるかもしれません。

Schema::connection('tenant1')->create('users', function($table)

3)残念ながら、シードはまだ複数の接続をサポートしているとは思いません。独自のシード機能をロールする必要がある場合があります。

于 2013-01-25T15:04:18.440 に答える