Laravel迁移报错多因数据库配置错误或迁移状态异常:.env中DB_USERNAME、DB_PASSWORD、DB_HOST填写错误或权限不足;DB_HOST应避免用localhost而用127.0.0.1;需执行config:clear刷新配置;“nothing to migrate”常因migrations表缺失或迁移文件命名不规范;字段修改失败需借助原生SQL或doctrine/dbal;生产环境迁移须加--force,敏感操作应分步实施,迁移文件不可修改。

迁移命令执行报错:`SQLSTATE[HY000] [1045] Access denied`
数据库连接配置不对,Laravel 根本连不上 MySQL。不是代码写错了,是 .env 里 DB_USERNAME、DB_PASSWORD 或 DB_HOST 填错了,或者对应用户没权限。
- 先用命令行直连验证:
mysql -u your_user -p -h 127.0.0.1,能进再去查 Laravel -
.env中的DB_HOST别写localhost——它在某些系统(尤其是 Docker)下会走 socket 而非 TCP,改用127.0.0.1更稳 - 运行迁移前务必执行
php artisan config:clear,否则改了.env也白搭,Laravel 会缓存旧配置
执行 php artisan migrate 提示“nothing to migrate”
不是命令失效,是 Laravel 认为所有迁移都已记录在 migrations 表里。可能你手动删过表、换过数据库,或迁移文件没被识别。
- 检查
database/migrations/下文件名是否符合格式:2023_01_01_000000_create_users_table.php(年_月_日_时分秒_描述) - 确认
migrations表存在且不为空;如果刚初始化数据库却提示 nothing,可能是php artisan migrate:install没跑过(Laravel 9+ 通常自动触发,但低版本需手动) - 想重跑全部迁移?别直接删表。用
php artisan migrate:reset回滚,再php artisan migrate——前提是每个down()方法都写对了
迁移中使用 Schema::table() 修改字段失败
MySQL 默认不支持某些修改,比如对含数据的字段改类型、加 NOT NULL 且无默认值,会直接报错。
- 用
DB::statement()手写原生 SQL 是最可控的方式,尤其涉及 JSON 字段、全文索引等复杂操作 - 修改字段前,先用
php artisan tinker运行DB::select('SHOW COLUMNS FROM users LIKE "email"');看当前定义,避免假设 - Laravel 10+ 的
$table->string('email')->change()需要安装doctrine/dbal,且仅对部分变更生效;不是所有字段都能“安全 change”
生产环境不敢跑 migrate?该加什么防护
迁移不是“本地测试完就 push 上线”,它本质是 DDL 操作,锁表、阻塞查询、甚至丢数据。线上必须设防。
- 永远带上
--force参数才允许在 production 环境执行,否则 Laravel 会拦住 —— 别在部署脚本里漏掉它 - 敏感变更(如删列、改类型)必须拆成多步迁移:先加新字段 → 同步写入双份 → 切读逻辑 → 清理旧字段,而不是一锤子 ALTER
- 用
php artisan migrate --pretend看最终生成的 SQL,特别是涉及大表时,确认有没有隐式锁表或全表扫描
迁移文件一旦合并进主干,就别改内容——哪怕只是注释。时间戳和类名共同构成唯一标识,改了会导致本地和线上 migration 状态错乱,比数据不一致还难排查。










