我实际上遇到了同样的问题,Joe 的答案在我的情况下不起作用,因为我有不同的数据库连接(所以不同的主机、端口、用户和密码)。
因此迁移必须一直进行大量的重新连接:
- 迁移从默认数据库开始(在我的例子中是 client_1)
- 从表
migrations 和 clients 获取内容
- 断开默认数据库
- 连接到client_2的数据库,运行迁移部分,断开client_2
- 再次连接默认数据库,存储迁移“日志”
然后为每个客户端循环它。
/**
* 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 中。
不过,注意两个DB::disconnect();。如果没有这些,情况会变得糟糕,因为迁移日志会存储在另一个客户端的数据库等中。
啊,顺便说一句,ClientController 并没有什么特别之处:
public static function returnDatabasesForArtisan()
{
return Client::select('*')->with('database')->get();
}