Laravel 6+ 的 db:seed 默认无反应,因 DatabaseSeeder 为空且需手动调用 $this->call(UserSeeder::class);工厂插入失败多因 $fillable 漏字段、NOT NULL 缺默认值、时间类型错配或误用 ->make();大批量用 DB::table()->insert() 并关闭事件;生产环境须硬性校验环境或配置 allow_seeding。

直接运行 php artisan db:seed 没反应,不是命令错了,是 Laravel 6+ 默认的 DatabaseSeeder 是空的——你得手动注册自己的填充器,否则它根本不知道该跑谁。
为什么 db:seed 什么都没发生
常见现象:执行命令后控制台安静退出,数据库没多一条记录。核心原因就一个:DatabaseSeeder::run() 方法里没写 $this->call(UserSeeder::class)。
- Laravel 6+ 不再自动扫描
database/seeders下所有类,必须显式调用 - 新建的
UserSeeder.php文件即使存在,不注册就等于不存在 - 如果用了子目录(比如
database/seeders/Users/UserSeeder.php),还要确认use语句路径正确,否则报Class "UserSeeder" not found - 想临时绕过,可用
php artisan db:seed --class=UserSeeder,但上线前别依赖这个方式
User::factory()->count(50)->create() 为什么插不进数据
这行代码看着简洁,但失败点极多,多数卡在模型层校验或数据库约束上。
- 模型
$fillable漏字段:比如工厂返回了'email_verified_at' => now(),但模型没把该字段加进$fillable,就会抛MassAssignmentException - 数据库 NOT NULL 字段没默认值,工厂又没提供:MySQL 直接报
Field doesn't have a default value - 时间字段类型错配:模型用
datetime,数据库是timestamp,Faker 返回带微秒的时间戳可能被截断 -
->make()和->create()混用:前者只生成内存对象,后者才真正 INSERT;新手常写了->make()还以为数据进库了
批量插入超 1000 条时怎么避免 OOM 或超时
Eloquent 每次 create() 都触发事件、类型转换、验证,1000 条 ≈ 1000 次查询 + 内存开销,很容易崩。
- 改用原生批量插入:
DB::table('users')->insert($data),其中$data是二维数组,键名必须和数据库字段完全一致(如'deleted_at'得传null,不能传字符串'null') - 时间字段统一用
now()或$this->faker->dateTimeThisYear(),避开时区与精度陷阱 - 唯一字段(如 email)跨批次重复?加
true启用全局缓存:$this->faker->unique(true)->safeEmail(),或干脆用str()->random(10).'@example.com'拼接 - 大数量填充前,建议先关掉模型事件:
User::withoutEvents(function () { User::factory()->count(2000)->create(); });
怎么防止误在生产环境跑填充
填充不是迁移,Laravel 不做环境自动隔离。靠 APP_ENV=production 判断不可靠,有些预发环境也设成 local。
- 在 Seeder 开头加硬性判断:
if (! app()->environment('local', 'testing')) { return; } - 更稳妥的是加配置项:
'allow_seeding' => env('ALLOW_SEEDING', false),Seeder 里检查config('app.allow_seeding') - 运行时强制加
--force才能突破环境限制,但命令本身不阻止你手抖——逻辑拦截才是最后一道防线
最容易被忽略的其实是软删除字段和时间字段的 null 表示方式:数据库要的是 SQL NULL,不是字符串 'null',也不是空字符串;哪怕只错一个字段,整批插入都可能静默失败或报 Data truncated。


















