Laravel迁移只认config/database.php中connections键名,不读模型$connection属性,必须用--database显式指定连接名,且需确保配置已清除缓存、连接名完全匹配、表名隔离以避免冲突。

php artisan migrate --database 参数必须显式指定连接名
不加 --database 就默认走 default 连接,哪怕模型里写了 $connection = 'mysql_analytics' 也完全不影响迁移行为。Laravel 的迁移系统和 Eloquent 模型是两套逻辑,迁移只认配置里的连接键名,不读模型定义。
常见错误现象:在 App\Models\AnalyticsEvent::class 中设置了 $connection = 'mysql_analytics',然后跑 php artisan migrate,结果表建到了主库而不是分析库。
- 必须用
php artisan migrate --database=mysql_analytics才会把迁移应用到对应连接 - 连接名要和
config/database.php的connections数组 key 完全一致(全小写、无空格、无特殊符号) - 如果连接名是
mysql2,就不能写成mysql_2或MYSQL2,否则报错Database [mysql_2] not configured. - 执行前确认已运行
php artisan config:clear,否则新添加的连接可能因缓存未更新而不可见
多个数据库迁移文件不能混用,得靠命名或目录隔离
Laravel 不支持“某个迁移只对特定连接生效”的自动路由机制。所有迁移文件都会被加载,但最终执行在哪条连接上,只取决于你传的 --database 参数。这意味着同一份迁移文件,可能在不同连接上重复执行——比如你给主库和分析库都跑了 php artisan migrate --database=xxx,又没做判断,就可能建两次同名表,直接报错。
- 推荐按连接分目录:如
database/migrations/mysql/和database/migrations/mysql_analytics/,再配合自定义 Artisan 命令或 shell 脚本调用 - 或者统一放
database/migrations/,但迁移类中手动检查连接:在up()开头加if ($this->getConnection()->getDatabaseName() !== 'analytics_db') return; - 更稳妥的做法是:不同库的迁移文件操作不同表,避免命名冲突;例如主库建
users,分析库建event_logs,天然隔离 - 不要依赖
Schema::connection('xxx')在迁移里切换——它只影响当次 Schema 操作,不改变当前迁移上下文的连接归属
DB::connection() 在迁移里无效,别试图动态切库
迁移类的 up() 和 down() 方法中,Schema 和 DB 门面默认绑定的是当前迁移命令所指定的连接。你在里面写 DB::connection('mysql_analytics')->table('x')->get() 是能执行的,但这只是临时查数据,不会改变迁移目标库,也不会让后续 Schema::create() 跑到那个库上。
-
Schema::create()总是作用于当前迁移上下文的连接,不是DB::connection()当前持有的那个 - 想在迁移中跨库操作(比如从主库读数据,写到分析库),得显式用
DB::connection('xxx')+ 原生查询,但要注意事务无法跨库生效 - 如果真需要这类逻辑,建议拆成两个独立迁移:一个负责建表,一个用 Seeder 或单独命令补数据
- 别在迁移里调用模型——模型自带
$connection属性,但迁移环境不保证模型已加载或连接可用,容易出Class not found或连接异常
多数据库迁移后,缓存与环境变量必须同步更新
开发时改了 .env 里的 DB_ANALYTICS_HOST,但忘了清缓存,或者部署时没把新环境变量推到服务器,迁移看着成功了,其实连的是旧地址或 fallback 到 127.0.0.1,表建到了意料之外的地方。
- 每次新增连接后,必须运行
php artisan config:clear;Laravel 不会热重载config/database.php里的新键 - 检查是否真读到了变量:在 Tinker 里运行
config('database.connections.mysql_analytics.host'),看输出是不是你预期的值 - Docker 或 CI 环境中,确保
.env文件被正确挂载或注入,而不是只靠php artisan config:cache生成的缓存文件 - 生产环境禁止用
env()直接读取——虽然 Laravel 允许,但性能差且易出错;应提前用php artisan config:cache固化配置


















