迁移报错应先检查状态一致性与配置对齐:查migrations表记录、确认.env数据库连接、验证up()中隐性依赖;“nothing to migrate”因laravel依据表记录而非文件存在判断;文件须在database/migrations/下且命名规范;回滚失败多因batch值异常或down()未处理外键;开启app_debug=true才能看到真实sql错误。

迁移报错别急着删文件或重装,90% 的问题出在状态不一致或配置没对齐——先看 migrations 表有没有记录、再确认 .env 连的是哪个库、最后检查 up() 里有没有隐性依赖。
迁移提示 “Nothing to migrate” 却明明新增了文件
这不是命令失效,是 Laravel 已经“记住”你没跑过它,但判断依据不是文件存在,而是 migrations 表里有没有对应记录。
- 运行
php artisan migrate:status,看新迁移文件名是否出现在列表中、batch值是否为0或空 - 手动查表:
SELECT * FROM migrations WHERE migration LIKE '%create_posts_table%';,如果结果为空,说明 Laravel 根本没识别到这个文件 - 检查文件路径:必须在
database/migrations/下,且命名严格符合2024_05_10_123456_create_posts_table.php格式(时间戳+下划线+小写蛇形) -
.env中的DB_DATABASE和DB_CONNECTION是否填错?连错库会导致迁移静默执行在测试库,而你在生产库看到“没变化”
回滚失败:migrate:rollback 没反应或报错
回滚不是“撤销上一个文件”,而是撤掉 batch 值最大的那一批——哪怕那批只含一个迁移,也可能因 down() 写法不当直接崩掉。
- 先执行
php artisan migrate:status,确认最高batch≥ 1;如果全是0,说明这些迁移从未被正式登记(比如手动删过表但没清migrations表),migrate:rollback必然无动作 -
down()方法里用了Schema::drop('table')?改成Schema::dropIfExists('table'),否则表不存在时直接抛异常中断 - 外键约束阻止删表?在
down()开头加DB::statement('SET FOREIGN_KEY_CHECKS = 0');,末尾再设回1 - 类找不到(如删了迁移文件又回滚)?立刻运行
composer dump-autoload,否则自动加载器找不到类,报Class not found
迁移执行中报 SQL 错误,但日志没细节
Laravel 默认把 PDO 异常吞掉一层,只留最外层提示。真正原因往往藏在底层 SQL 或连接上下文里。
- 打开
.env,确保APP_DEBUG=true—— 否则你只能看到 “SQLSTATE[42S02]” 这种泛型码,看不到具体哪条语句失败 - 错误信息里带
Base table or view not found?大概率是 Seeder 提前触发了,而它依赖的表还没建好;查migrations表,确认create_modules_table这类前置迁移是否真被执行(记录存在 ≠ 表存在,Laravel 不校验物理表) - 报
Specified key was too long?不是迁移语法错,是 utf8mb4 下索引长度超限;必须在AppServiceProvider::boot()加Schema::defaultStringLength(191),否则string(255)->unique()直接失败 - 用 PostgreSQL 迁移后首页正常、但 POST 接口 500?极可能是
bootstrap/cache/config.php缓存了旧数据库配置或APP_KEY缺失,先php artisan config:clear && php artisan config:cache
强制指定 utf8mb4 却仍存不了 emoji
仅改 config/database.php 中的 charset 和 collation 不够,Laravel 9.x 及之前版本的 Schema::create() 构建器默认忽略它们。
- 建表后必须补一句:
DB::statement("ALTER TABLE `posts` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci");,且放在up()最末尾,和Schema::create()同事务 - 给字段单独设排序规则:
$table->string('title')->collation('utf8mb4_unicode_ci');,但注意integer()、json()等类型不支持collation(),调用会静默失败 - 想绕过构建器限制?用
$table->addColumn('VARCHAR', 'bio', ['length' => 500, 'collation' => 'utf8mb4_bin']);,但需确认 MySQL 版本 ≥ 5.7.8
真正卡住人的从来不是语法,而是状态错位:migrations 表说跑过了,其实表被手动删了;.env 写着 mysql,实际连的是 pgsql;APP_DEBUG=true 没开,错误就永远藏在黑盒里。每次迁移前,先 php artisan migrate:status + grep APP_KEY .env + tail -n 20 storage/logs/laravel.log,三件事做完,八成问题已经浮出水面。











