Seeder 跑完表为空,主因是未建表、未注册调用或唯一约束导致静默失败;需确保已迁移、正确调用 Seeder、字段名类型匹配、Faker locale 显式设置,并在 Laravel 10+ 中改用 new UserSeeder() 实例化。

Seeder 跑完表还是空的?大概率不是代码写错了,而是根本没建表、没注册调用、或唯一约束拦住了插入——它不报错,只沉默失败。
php artisan db:seed 什么都没发生?先查迁移和注册
Seeder 本身不建表,也不自动清空旧数据。如果 users 表压根不存在,UserSeeder 插入会静默跳过(Laravel 9+ 默认关闭异常抛出)。必须先确保:
-
php artisan migrate已成功执行,且目标数据库正确(检查.env中的DB_DATABASE) -
DatabaseSeeder.php的run()方法里显式调用了你的 Seeder:$this->call(UserSeeder::class) - 类名、文件名、命名空间三者严格一致:比如
UserSeeder.php→class UserSeeder→namespace DatabaseSeeders; - Laravel 8+ 后不再自动扫描
database/seeders目录,漏掉$this->call()就等于没写
UserSeeder 里用 DB::table()->insert() 没反应?字段和类型是关键
用查询构造器批量插入时,字段名必须与数据库列名**完全一致**(包括下划线/驼峰),且值类型要匹配。常见失效点:
-
DB::table('users')->insert(['user_name' => fake()->name()])→ 若实际字段是name,这条就白插了 -
'email_verified_at' => '2024-01-01'→ 必须是now()或Carbon::parse()实例,字符串直接被忽略 - NOT NULL 字段没提供值,且数据库没设默认值,整条插入会被 MySQL 拦截,但 Laravel 不抛异常(除非开启严格模式)
- 建议搭配
DB::table('users')->truncate()放在run()开头,避免重复运行时主键冲突
Laravel 10+ 调用子 Seeder 报 Class not found?别再传字符串或 ::class
Laravel 10+ 废弃了 $this->call(UserSeeder::class) 这种写法,改用原生实例化。错误写法会导致 Class "UserSeeder" does not exist:
- ❌
$this->call('UserSeeder')(字符串) - ❌
$this->call(UserSeeder::class)(常量,仍触发旧机制) - ✅ 正确写法:
$this->call(new UserSeeder()),并提前use DatabaseSeedersUserSeeder; - 如果
UserSeeder不在DatabaseSeeders下,必须写全路径:new AppSeedersUserSeeder() - 同时确认
composer.json的psr-4包含了工厂目录:"Database\Factories\": "database/factories/",改完后跑composer dump-autoload
fake()->email() 返回空或英文?locale 和 unique() 作用域要盯紧
Faker 默认 locale 是 en_US,中文项目必须显式指定,否则 fake()->name() 可能返回空或乱码;unique() 也只在单次 count() 调用内有效:
-
fake('zh_CN')->name()→ 中文姓名,不是fake()->name('zh_CN')(语法错) -
User::factory()->count(100)->create()→unique()->email()在这 100 条内保证不重复 -
for ($i = 0; $i create(); }→ 每次都是新上下文,unique()失效,极易触发Duplicate entry - 外键字段如
user_id,若关联模型未提前存在,Eloquent 会静默跳过该字段(不是报错),导致数据不完整
最常被跳过的其实是 DatabaseSeeder 里的调用逻辑和 Faker 的 locale 配置——它们不出错,但让填充结果彻底偏离预期。


















