可使用 php artisan migrate:rollback --path 指定单个迁移文件回滚,路径须为 database/migrations/ 开头、含年份前缀和 .php 后缀;若该文件不在最新 batch 则空跑不报错;重跑需先 rollback 再 migrate --path,但后者默认跳过已记录的迁移。

只回滚某一个迁移文件,用 php artisan migrate:rollback --path
默认 php artisan migrate:rollback 会撤回上一批(batch)所有迁移,没法精准控制到单个文件。真要只撤回一个,必须用 --path 参数指定完整路径。
路径是相对于 database/migrations/ 目录的,且必须带年份前缀和 .php 后缀:
php artisan migrate:rollback --path=database/migrations/2023_05_12_102433_create_orders_table.php
- 路径写错(比如漏了
database/migrations/前缀,或用了相对路径如./2023_...)会报错:Migration not found - 该文件若不在最新 batch 中(比如它属于上上批),命令仍会执行——但实际只是“空跑”,不会报错,也不会真正回滚任何表结构
- 如果该迁移的
down()方法里有依赖其他表的操作(比如删外键、删被引用的表),而那些表已被后续迁移改过或删掉,就会直接抛出 SQL 错误
重跑某一个迁移文件(先 rollback 再 migrate)
Laravel 没有内置的 “re-migrate single file” 命令,得手动两步走。注意顺序不能反,否则可能报 Table already exists 或 Base table or view already exists。
- 先确认目标迁移已执行过(查
migrations表,看对应migration字段值是否存在) - 执行回滚:
php artisan migrate:rollback --path=database/migrations/xxx.php - 再执行迁移:
php artisan migrate --path=database/migrations/xxx.php - 如果
up()方法里用了Schema::create(),而表还残留着(比如down()没清干净),第二步会失败;建议在up()开头加if (!Schema::hasTable('xxx')) { ... }防御
php artisan migrate --path 的行为边界
--path 不是“只运行这个文件”,而是“只加载并运行这个文件”,但它仍受 Laravel 迁移锁机制约束:如果该文件已在 migrations 表中记录为已执行,migrate 命令会跳过它,不报错也不提示。
- 想强制重跑,只能先手动删
migrations表里对应那条记录(字段migration值匹配文件名),再跑migrate --path -
--path不支持通配符或多个路径,一次只能传一个文件 - Windows 下路径分隔符用正斜杠
/,别用反斜杠\,否则解析失败 - 如果迁移文件里调用了
Artisan::call('migrate')或依赖其他迁移的状态,单独跑它很可能出逻辑错误——--path是脱离上下文的孤立执行
更安全的替代做法:用 --step + 手动调整
当迁移之间有强依赖(比如 A 创建表、B 加字段、C 加索引),硬拆单文件容易破坏一致性。这时不如用 --step 控制批次粒度:
php artisan migrate:rollback --step=1
然后检查 migrations 表最后几条记录,确认哪几个是你想处理的,再决定是删记录后重跑,还是直接编辑迁移文件内容并 php artisan migrate:fresh --seed(仅限本地/开发环境)。
真正麻烦的从来不是命令怎么敲,而是迁移文件里写的 SQL 是否幂等、down() 是否真能逆向、以及团队里其他人有没有基于你刚回滚的结构写了新代码——这些都得靠人盯,命令帮不上忙。











