laravel数据库迁移问题90%源于执行顺序、文件归属和回滚策略不一致;必须用php artisan make:migration生成带时间戳文件,禁止手改时间戳或手动删migrations表,外键依赖靠时间戳硬约束,改字段须装doctrine/dbal并新建迁移,seeder须与迁移绑定提交且类名路径一致,生产环境禁用--force直接seed,上线前务必用migrate:status校验环境一致性。

团队协作中,Laravel 数据库迁移出问题,90% 不是语法写错,而是执行顺序、文件归属和回滚策略没对齐。必须用 php artisan make:migration 生成带时间戳的文件,且所有成员共享同一套迁移历史——migrations 表不能手动删、不能跳过、不能本地改库绕过。
迁移文件必须由 Artisan 生成,禁止手建或改时间戳
多人并行开发时,有人直接新建 PHP 文件、有人手动改文件名里的日期(比如把 2026_06_01_100000 改成 2026_06_01_099999 抢执行顺序),这会导致上线失败或本地能跑线上崩。
-
php artisan make:migration create_orders_table --create=orders是唯一合规入口,它保证时间戳基于当前系统时间且全局唯一 - 时间戳不是“创建时间”,而是“预期执行顺序”——Laravel 按前缀升序执行,不看 Git 提交时间或文件修改时间
- 外键依赖必须靠时间戳硬约束:若
create_users_table.php是2026_06_01_100000,则create_posts_table.php引用users.id的文件时间戳必须 >2026_06_01_100000 - 已提交到 Git 的迁移文件,禁止编辑其时间戳部分;哪怕只是重命名,也会破坏其他成员的
php artisan migrate:status判断
修改字段必须装 doctrine/dbal,且只能新建迁移
直接编辑老迁移文件里的 up() 方法改字段类型,或者在已有迁移里加 $table->string('email')->change() 却没装 doctrine/dbal,都会导致静默失败或报错 SQLSTATE[HY000]: General error: 1833 Cannot change column 'email': used in a foreign key constraint。
PHP中文网提供Laravel 13.2.0版本下载,Laravel框架 是基于 PHP 8.3+ 的高性能框架,官方推荐通过 Composer 安装。它内置 AI SDK、JSON:API Resources 及原生向量搜索,支持属性驱动开发与队列路由,大幅提升开发效率。相比旧版,13.2.0 优化了缓存 TTL 管理与实时通信,无需 Redis 即可横向扩展。作为现代 Web 开发首选,它兼顾安全与极速体验,助您快速构建企业级应用。
- 先运行
composer require doctrine/dbal,否则change()方法根本不会触发 ALTER TABLE - 改字段必须走新迁移:比如要扩大
name长度,就php artisan make:migration change_name_length_on_users_table --table=users -
up()中必须链式调用->change(),只写$table->string('name', 100)不生效 -
down()要严格可逆:如果up()把长度从 50 改成 100,down()就得改回 50,不能写成dropColumn或留空
Seeder 和 Migration 必须绑定提交,不可分离管理
有人只提交迁移文件,忘了提交对应的 DatabaseSeeder.php 或自定义 Seeder 类,结果 CI 流水线跑 php artisan migrate && php artisan db:seed 时爆 Class App\Database\Seeders\UserSeeder does not exist。
- 每个业务模块的初始数据(如管理员账号、基础配置项)必须有对应 Seeder,并在
DatabaseSeeder@run()中显式调用 - Seeder 文件也要进 Git,路径为
database/seeders/,类名需与文件名一致(如UserSeeder.php→UserSeeder) - 生产环境禁用
php artisan db:seed --force,应改用带条件判断的 Seeder,例如检查users表是否为空再插入 - 避免在 Seeder 中调用模型事件(如
User::created),防止因监听器副作用导致填充失败
上线前必须验证迁移状态,而非只信本地成功
本地 php artisan migrate 成功 ≠ 上线成功。常见坑是本地用 MySQL 8,线上用 MySQL 5.7,json 字段或 enum 默认值不兼容,或者未声明 collation 导致排序异常。
- 上线前执行
php artisan migrate:status,确认所有待执行迁移在目标环境也处于 “Pending” 状态 - 预发布环境必须和生产环境数据库版本一致,且执行过完全相同的迁移序列
- 关键迁移(如加非空字段、删列)必须加
--pretend先看 SQL:php artisan migrate --pretend - 生产环境执行迁移必须带
--force,否则命令会交互式询问,卡在 CI 或部署脚本里
真正难的不是写对一行 $table->timestamps(),而是让所有人对“哪个文件该什么时候跑、谁负责回滚、出错后怎么对齐状态”有统一预期。时间戳、doctrine/dbal、migrate:status 这三样东西,比语法细节更值得每天确认一遍。










