私のアプリでは、すべてのユーザーが、ユーザー登録時に作成された独自のデータベースを持っています。接続とデータベースデータ(データベース名、ユーザー名、パスワード)は、デフォルトデータベースのテーブルに保存されます。
try{
DB::transaction(function() {
$website = new Website();
$website->user_id = Auth::get()->id;
$website->save();
$database_name = 'website_'.$website->id;
DB::statement(DB::raw('CREATE DATABASE ' . $database_name));
$websiteDatabase = new WebsiteDatabase();
$websiteDatabase->website_id = $website->id;
$websiteDatabase->database_name = $database_name;
$websiteDatabase->save();
});
} catch(\Exception $e) {
echo $e->getMessage();
}
次に、新しいユーザーのデータベースを作成した後、そのデータベースでいくつかの移行を実行したいと思います。
出来ますか?
ありがとう
App/config/database.phpで次のことを行う必要があります。
<?php
return array(
'default' => 'mysql',
'connections' => array(
# Our primary database connection
'mysql' => array(
'driver' => 'mysql',
'Host' => 'Host1',
'database' => 'database1',
'username' => 'user1',
'password' => 'pass1'
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
),
# Our secondary database connection
'mysql2' => array(
'driver' => 'mysql',
'Host' => 'Host2',
'database' => 'database2',
'username' => 'user2',
'password' => 'pass2'
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
),
),
);
移行で2つのデータベース接続を準備したので、次のことができます。
Schema::connection('mysql2')->create('some_table', function($table)
{
$table->increments('id');
});
これはうまくいくはずです。詳細: http://fideloper.com/laravel-multiple-database-connections
データベース構成をdatabase.php
ファイル、これはあなたを助けることができます:
php artisan migrate --database=**otherDatabase**
実際には同じ問題に直面し、データベース接続が異なるため(ホスト、ポート、ユーザー、パスが異なるため)、ジョーの答えは私の場合には機能しませんでした。
したがって、移行では常に多くの再接続を行う必要があります。
migrations
およびclients
からデータをフェッチしますそして、クライアントごとにループします。
_ /**
* Run the migrations.
*
* @return void
*/
public function up()
{
$defaultConnection = BackendConfig::getDatabaseConfigArray();
$clients = ClientController::returnDatabasesForArtisan();
foreach ($clients as $client) {
BackendConfig::setDatabaseFromClient($client);
Schema::create('newtable', function (Blueprint $table) {
$table->increments('id')->unsigned();
$table->timestamps();
});
BackendConfig::setDatabaseFromArray($defaultConnection);
}
}
_
そして、魔法が保存されているクラス:
_class BackendConfig
{
public static function getDatabaseConfigArray($client_id = 1)
{
$connection = config('database.default');
return [
'id' => $client_id,
'Host' => config("database.connections.$connection.Host"),
'port' => config("database.connections.$connection.port"),
'username' => config("database.connections.$connection.username"),
'password' => config("database.connections.$connection.password"),
];
}
public static function setDatabaseFromArray($array)
{
self::setDatabase($array['id'], $array['Host'], $array['port'], $array['username'], $array['password'], true);
DB::disconnect();
}
public static function setDatabaseFromClient(Client $client)
{
DB::disconnect();
self::setDatabase($client->id, $client->database->Host, $client->database->port, $client->database->username, $client->database->password, true);
}
public static function setDatabase($client_id, $Host, $port, $username, $password)
{
$connection = config('database.default');
$database_name = $connection . '_' . $client_id;
config([
"database.connections.$connection.database" => $database_name,
"database.connections.$connection.Host" => $Host,
"database.connections.$connection.port" => $port,
"database.connections.$connection.username" => $username,
"database.connections.$connection.password" => $password,
]);
}
_
このソリューションを使用すると、すべてのクライアントでまったく同じ移行を実行できますが、移行は私の種類のマスタークライアントであるclient_1に格納されるだけです。
ただし、2つのDB::disconnect();
に注意してください。移行ログは別のクライアントのデータベースなどに保存されるため、このような状況がなければ、状況が台無しになります。
ああ、ところでClientControllerは特別なことは何もしません:
_public static function returnDatabasesForArtisan()
{
return Client::select('*')->with('database')->get();
}
_
同じ問題があります。私の解決策は、最初に_Config::set
_を使用してデータベースを変更し、次にArtisan::call("migrate")
を実行することです。あなたのコードに基づいて:
_DB::statement(DB::raw('CREATE DATABASE ' . $database_name));
Config::set('database.connections.mysql.database', $database_name);
Artisan::call("migrate --database=mysql");
_
構成はセッションでのみ変更され、後で現在の設定としてリセットされます。
最善の解決策は、このメソッドをAppServiceProvide
で呼び出すことです。
これは、この種の問題の最良の解決策です。私はこれを私のプロジェクトで使用しています。私の場合、2つの環境DevelopmentおよびProductionがあります。そのため、プロジェクトが開発モードの場合、ローカルサーバーまたはライブサーバーを検索します。したがって、ここでdynamic-DBコンセプトを設定できます。
関数を作成する必要がありますboot()Functionの内部でこれを呼び出す必要がありますApp\Providers\AppServiceProvide.php
public function boot()
{
DBConnection();
}
私はHelperファイルを作成しました。だから私のコードはhelper.php
function DBConnection()
{
if( env('APP_ENV') == 'local' )
{ $databse_name = "test_me";
$Host = '127.0.0.1';
$user="root";
$password="";
}
else
{
$databse_name = 'tic_tac';
$Host = 'localhost';
$user="";
$password="";
}
$state = true;
try {
Config::set('database.connections.myConnection', array(
'driver' => 'mysql',
'Host' => $Host,
'database' => $databse_name,
'username' => $user,
'password' => $password,
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
'strict' => false,
));
/* \DB::setDefaultConnection('myConnection');
$state = \DB::connection()->getPdo();*/
Config::set('database.connections.myConnection.database', $databse_name);
\DB::setDefaultConnection('myConnection');
\DB::reconnect('myConnection');
} catch( \Exception $e) {
$state = false;
}
return $state;
}
別のデータベース接続を使用するつもりなら、それはドキュメントに存在します:
Schema::connection('foo')->create('users', function (Blueprint $table) {
$table->bigIncrements('id');
});
私はようやくこの混乱を理解したと思います...このソリューションは各テナントのデータベースの構成を必要とせず、一度だけ実行する必要があります。
class MigrationBlah extends Migration {
public function up() {
$dbs = DB::connection('tenants')->table('tenants')->get();
foreach ($dbs as $db) {
Schema::table($db->database . '.bodegausuarios', function($table){
$table->foreign('usuario')->references('usuarioid')->on('authusuarios');
});
}
}
}
私のdatabase.phpに「tenants」という名前の接続があり、すべてのテナントのデータベース名が含まれています。テナントデータベースにもデフォルトの接続を設定しています。そのデータベースは、migrationsテーブルの処理を担当するデータベースです。
Foreachステートメントを使用すると、テナントデータベースを通過し、各データベースで移行を実行します。
デフォルトの接続では、すべてのテナントのデータベースにアクセスできるユーザーを構成して、それを機能させる必要があります。
これは、どの移行がどのデータベースに対応するかを覚えるのは面倒です。
Laravel 5.5の場合、私はこのアプローチを使用しました:
public function up()
{
// this line is important
Illuminate\Support\Facades\DB::setDefaultConnection('anotherDatabaseConnection');
Schema::table('product',
function (Blueprint $table)
{
$table->string('public_id', 85)->nullable()->after('ProductID');
});
// this line is important, Probably you need to set this to 'mysql'
Illuminate\Support\Facades\DB::setDefaultConnection('nameOfYourDefaultDatabaseConnection');
}
すべての移行は、実行時に手動でデータベースを指定する必要がなく、自動的に実行できます。
移行テーブルはデフォルトのデータベース内に保存されていることに注意してください。