多数据库迁移失败:自定义命令加载站点配置后无法执行migrate
Laravel多站点数据库迁移命令故障排查与修复
核心问题分析
你的代码存在三个关键问题导致迁移失败:
- 数据库连接未重新初始化:直接修改
config()数组后,Laravel已初始化的数据库连接实例不会自动更新,migrate命令仍会复用旧连接配置。 env()函数在配置缓存后失效:项目开启配置缓存(php artisan config:cache)后,env()仅在配置加载时读取一次,后续调用无法获取动态拼接的环境变量值。- 未明确指定迁移使用的数据库连接:默认
migrate命令使用默认连接,即使修改了配置,也无法强制切换到目标站点的数据库。
修复后的代码示例
use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Artisan; $sites = Site::all(); $defaultConnection = config('database.default'); foreach ($sites as $site) { $this->info("Running migrations on Site: {$site->name}:{$site->id}"); // 构建站点专属数据库连接配置 $connectionName = "site_{$site->id}"; config()->set("database.connections.{$connectionName}", [ 'driver' => config("database.connections.{$defaultConnection}.driver"), 'host' => config("database.connections.{$defaultConnection}.host"), 'port' => config("database.connections.{$defaultConnection}.port"), 'database' => env("DB_DATABASE_{$site->id}"), 'username' => env("DB_USERNAME_{$site->id}"), 'password' => env("DB_PASSWORD_{$site->id}"), 'charset' => config("database.connections.{$defaultConnection}.charset"), 'collation' => config("database.connections.{$defaultConnection}.collation"), 'prefix' => config("database.connections.{$defaultConnection}.prefix"), ]); // 执行迁移,明确指定使用新创建的连接 Artisan::call('migrate', [ '--database' => $connectionName, '--force' => true, // 生产环境必填,跳过交互确认 ]); // 清除连接实例,避免下一次循环复用旧配置 DB::purge($connectionName); DB::purge($defaultConnection); }
额外注意事项
- 避免生产环境直接调用
env():建议将站点数据库配置写入config/database.php,例如新增site_connections数组统一管理,确保配置缓存后仍能正常读取。 - 验证环境变量存在性:可添加判断逻辑,若站点对应的环境变量不存在,直接跳过或抛出错误提示,避免无效迁移。
- 测试模式下的迁移:本地测试时可移除
--force参数,保留交互确认环节,防止误操作。
内容的提问来源于stack exchange,提问作者Ali Rasheed
相关产品推荐
相关产品推荐

