我正在制作多租户申请。由于我选择为每个租户配备数据库,然后是" master" 数据库,其中包含有关不同租户的元信息等。
因此,我将迁移分为两个目录:
租户 - 包含每个租户数据库的迁移。
每次迁移时,我都不必指定迁移文件夹和要运行的数据库的路径,而是创建了一个控制台命令。然而,这就是问题发生的地方。
我使用子域作为要加载数据库的标识符来处理租户,使用这样的中间件:
public function handle($request, Closure $next)
{
$domains = explode('.', parse_url($request->url())['host']);
if (count($domains) < 3)
return app()->abort(403, "A valid subdomain is required");
\Config::set('database.connections.tenant.database', $domains[0]);
return $next($request);
}
这适用于网络。
但是当我在我的控制台命令中使用Config::set()
时,它会被忽略,而Laravel只是使用我的.env文件中的那个。
数据库配置文件:
return [
'default' => env('DB_CONNECTION', 'tenant'),
'connections' => [
'tenant' => [
'driver' => 'mysql',
'host' => env('DB_HOST', 'localhost'),
'database' => env('DB_TENANT_DATABASE'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', '')
],
'master' => [
'driver' => 'mysql',
'host' => env('DB_HOST', 'localhost'),
'database' => env('DB_MASTER_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
],
]
];
(我已经清理了一下,所以只显示了必需品。)
在我的.env文件中,我已经指定了一个默认租户数据库,该数据库在我使用cli时使用。
DB_HOST=127.0.0.1
DB_MASTER_DATABASE=master
DB_TENANT_DATABASE=company
DB_USERNAME=root
DB_PASSWORD=
在我的TenantMigrater中,我遍历每个租户,并使用不同的连接和路径为每个租户运行迁移。
foreach(Tenant::all() as $tenant)
{
$this->info("Running migrations for the tenant: {$tenant->name}");
\Config::set('database.connections.tenant.database', $tenant->database);
$this->call('migrate', [
'--database' => 'tenant',
'--path' => 'database/migrations/tenants/'
]);
}
虽然我为租户连接设置了一个新数据库,但它仍然会回落到.env文件中指定的数据库。
我尝试通过Laravel的迁移器,到目前为止我可以看到,名称正确地设置在配置中,所以我感到有点困惑。有什么想法吗?
编辑: 我想我已经向这个问题迈进了一步。看起来,当运行php artisan *时,cli以config / database.php文件中指定的名称启动与数据库的连接。当我尝试覆盖它时,连接已经打开连接(或者laravel认为),它只是将我的命令交给同一个连接,而不设置新数据库,因此它继续使用相同的数据库。但是,我不知道每次迭代租户时如何强制它创建新连接。
答案 0 :(得分:0)
正在运行\ DB ::重新连接(&#39;租户&#39;);在每次迁移之前似乎都能使它发挥作用。我认为这有点反直觉。