seeder不会建表,仅向已有表插入数据;若未执行php artisan migrate导致表不存在,插入将静默失败(laravel 9+默认),结果表为空;排查需先确认迁移状态和表是否存在,再处理唯一索引冲突或调用方式错误。

php artisan migrate 没跑,db:seed 肯定空
Seeder 不会建表,只负责往已有表里插数据。表都不存在,db:seed 执行时不会报错,但插入会静默失败(Laravel 9+ 默认行为),结果就是表看着“空”。
确认步骤:
- 运行
php artisan migrate:status,检查create_users_table这类迁移是否显示Ran - 进数据库手动查
SHOW TABLES;,确认users表真存在 - 别依赖
php artisan migrate:fresh --seed一次过——它只在当前命令下生效,如果中途失败,后续再跑db:seed仍可能因表缺失而空
Laravel 10+ 中 $this->call(UserSeeder::class) 报错 Class not found
新版 Laravel 废弃了 $this->call() 的字符串/类名调用方式,必须显式实例化并调用 run() 方法。
正确写法(以 DatabaseSeeder.php 为例):
use Database\Seeders\UserSeeder;
public function run()
{
(new UserSeeder())->run();
}
常见错误点:
- 没加
use Database\Seeders\UserSeeder;,直接写(new UserSeeder())->run()→ 找不到类 - 路径写错,比如实际文件在
database/seeders/Auth/UserSeeder.php,却用了use Database\Seeders\UserSeeder; - 误传字符串:
$this->call('UserSeeder')或$this->call(UserSeeder::class)→ 全部失效
Seeder 插入中断但没提示,表还是空的
最典型原因是唯一索引冲突(如 email 字段设了 unique()),而 Seeder 又重复插入相同值。Laravel 默认不抛异常,整批插入直接中断,且无日志提示。
排查与解决:
- 先清空目标表:
DB::table('users')->truncate();(推荐,跨引擎兼容) - 若需关外键约束(如涉及关联表):
DB::statement('SET FOREIGN_KEY_CHECKS=0');+truncate+SET FOREIGN_KEY_CHECKS=1 - 避免用
User::query()->delete()清表——会触发模型事件、软删除判断,慢且不可靠 - Seeder 内插数据前加
try/catch包裹单条或小批量插入,捕获Illuminate\Database\QueryException查具体 SQL 错误
批量插入卡死或超时,别用循环 create()
100 条以上数据用 User::create() 循环,性能断崖式下降:每条都走 Eloquent 生命周期、验证、事件、单条 INSERT。
提速方案:
- 纯插入、不走模型逻辑 → 用
DB::table('users')->insert($data),$data是二维数组,键名必须严格匹配字段名 - 要保留模型类型转换(如
$casts)、mutators 或事件 → 先User::unguard(),再User::insert($data) - 千级以上数据务必分块:
for ($i = 0; $i count(500)->create(); } - 时间字段注意:
DB::table()不自动转Carbon,得手动now()->format('Y-m-d H:i:s')
真正容易被忽略的是:Seeder 的执行顺序不靠 $this->call() 控制,而靠文件名排序。外键依赖的表(如 posts 依赖 users)必须确保 users 表 Seeder 文件名字典序更小,例如命名为 01_user_seeder.php 和 02_post_seeder.php。否则本地可能碰巧成功,CI 环境必崩。











