动态 env-files(多个数据库)和 artisan 命令
Dynamic env-files (multiple databases) and artisan commands
我有一个大型项目,每个客户都在自己单独的数据库中。为了让它工作,我们使用自定义 .env
-loader 加载每个客户 .env
通过检查客户子域(每个客户唯一)。
然而,这当然不适用于 artisan 命令。例如,当我要迁移时,我将需要一次迁移所有数据库。所以我设置了一个 Artisan 命令来获取 .env
文件并循环遍历它们,然后调用默认的 artisan migrate
。但它没有按预期工作。
我什么都试过了;例如:
$dotenv = new Dotenv('/env', '.test.env');
$dotenv->overload();
并且:
app()->useEnvironmentPath('/env');
app()->loadEnvironmentFrom('.test.env');
甚至:
config('database.connections.mysql.database', 'test_database');
一旦我 运行 $this->call('migrate');
应用默认为默认 .env
并在 运行 时忽略所有自定义。有谁知道我如何重载数据库的迁移命令选择?
注意: 我知道我可以在 config/database.php
中手动设置多个连接(例如:Overriding Default Laravel database configuration for artisan migrate commands),但是,图像有几十个客户,这不可行。
我不得不对控制台命令创建的 SQLite 数据库做一些类似的事情,我可以迁移到 运行 的唯一方法是动态创建数据库配置:
Config::set('database.connections.'.$config_key, array(
'driver' => 'sqlite',
'database' => storage_path($database_name),
'prefix' => '',
));
然后我会调用迁移命令:
Artisan::call('migrate', [
'--database' => $config_key,
'--path' => 'database/offline/'.$type.'/migrations',
]);
经过一大堆问题后,我可以这样排序;
在 Laravel 5 中,Config::set()
、config('config',['key' => 'value])
和 config()-set('config', ['key' => 'value'])
似乎有所不同。
经过大量测试不同的变体后,我们设法通过这种方式获得了解决方案;
$connection = 'connection';
$iterator = 0;
foreach ($files as $file) {
App::useEnvironmentPath('/env');
App::loadEnvironmentFrom('.file.env');
// Create a new connection "on the fly"
config()->set('database.connections.' . $connection . '_' . $iterator, [
'driver' => 'mysql',
'host' => env('DB_HOST'),
'database' => env('DB_DATABASE'),
'username' => env('DB_USERNAME'),
'password' => env('DB_PASSWORD'),
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
'strict' => false,
]);
// Call regular migration command
$this->call('migrate', ['--force' => true, '--database' => $connection . '_' . $iterator]);
$iterator++;
}
这设法为 MySQL-database 设置多个新连接,然后为每个连接设置种子。
感谢 @David Allen 的启发。
我有一个大型项目,每个客户都在自己单独的数据库中。为了让它工作,我们使用自定义 .env
-loader 加载每个客户 .env
通过检查客户子域(每个客户唯一)。
然而,这当然不适用于 artisan 命令。例如,当我要迁移时,我将需要一次迁移所有数据库。所以我设置了一个 Artisan 命令来获取 .env
文件并循环遍历它们,然后调用默认的 artisan migrate
。但它没有按预期工作。
我什么都试过了;例如:
$dotenv = new Dotenv('/env', '.test.env');
$dotenv->overload();
并且:
app()->useEnvironmentPath('/env');
app()->loadEnvironmentFrom('.test.env');
甚至:
config('database.connections.mysql.database', 'test_database');
一旦我 运行 $this->call('migrate');
应用默认为默认 .env
并在 运行 时忽略所有自定义。有谁知道我如何重载数据库的迁移命令选择?
注意: 我知道我可以在 config/database.php
中手动设置多个连接(例如:Overriding Default Laravel database configuration for artisan migrate commands),但是,图像有几十个客户,这不可行。
我不得不对控制台命令创建的 SQLite 数据库做一些类似的事情,我可以迁移到 运行 的唯一方法是动态创建数据库配置:
Config::set('database.connections.'.$config_key, array(
'driver' => 'sqlite',
'database' => storage_path($database_name),
'prefix' => '',
));
然后我会调用迁移命令:
Artisan::call('migrate', [
'--database' => $config_key,
'--path' => 'database/offline/'.$type.'/migrations',
]);
经过一大堆问题后,我可以这样排序;
在 Laravel 5 中,Config::set()
、config('config',['key' => 'value])
和 config()-set('config', ['key' => 'value'])
似乎有所不同。
经过大量测试不同的变体后,我们设法通过这种方式获得了解决方案;
$connection = 'connection';
$iterator = 0;
foreach ($files as $file) {
App::useEnvironmentPath('/env');
App::loadEnvironmentFrom('.file.env');
// Create a new connection "on the fly"
config()->set('database.connections.' . $connection . '_' . $iterator, [
'driver' => 'mysql',
'host' => env('DB_HOST'),
'database' => env('DB_DATABASE'),
'username' => env('DB_USERNAME'),
'password' => env('DB_PASSWORD'),
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
'strict' => false,
]);
// Call regular migration command
$this->call('migrate', ['--force' => true, '--database' => $connection . '_' . $iterator]);
$iterator++;
}
这设法为 MySQL-database 设置多个新连接,然后为每个连接设置种子。
感谢 @David Allen 的启发。