You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel Seeder仅插入1条数据,预期需插入2500条的问题

Laravel Seeder仅插入1条Post记录问题

问题情况

配置Seeder和Factory后,预期插入2500条Post记录,但实际仅插入1条。尝试过两种指定数量的方式均无效:

  • 直接在Factory构造时传入数量:Post::factory(self::NUMBER_OF_FAKE_POSTS)->create();
  • 使用count()方法指定数量:Post::factory()->count(self::NUMBER_OF_FAKE_POSTS)->create();

相关代码

Factory代码

public function definition(): array
{
    $timestamp = $this->getFakeTimestamp();

    return [
        'title' => $this->faker->sentence(),
        'body' => $this->faker->paragraph(),
        'more_inside' => $this->faker->paragraph(),
        'subsite_id' => (new Subsite())->inRandomOrder()->first(),
        'user_id' => (new User())->inRandomOrder()->first(),
        'created_at' => $timestamp,
        'published_at' => $timestamp,
        'updated_at' => null,
        'deleted_at' => null,
        'is_published' => true,
        'state' => PostStateEnum::Published->value,
    ];
}

Seeder代码

final class FakePostSeeder extends Seeder
{
    private const int NUMBER_OF_FAKE_POSTS = 2500;

    public function run(): void
    {
        DB::connection()->disableQueryLog();

        Post::factory(self::NUMBER_OF_FAKE_POSTS)->create();
    }
}

尝试过的count写法

public function run(): void
{
    DB::connection()->disableQueryLog();

    Post::factory()
        ->count(self::NUMBER_OF_FAKE_POSTS)
        ->create();
}

问题原因

问题出在subsite_id和user_id的赋值逻辑上:
(new Subsite())->inRandomOrder()->first()返回的是Subsite模型实例,而非字段需要的ID值。将模型实例直接赋值给整数类型的subsite_id/user_id字段,会导致数据库插入异常。批量插入时,第一条记录可能因隐式转换侥幸成功,但后续记录因类型不匹配被静默拦截,最终仅插入1条。

解决方案

修改Factory中subsite_id和user_id的赋值,明确获取模型的ID:

方案1:直接获取ID

public function definition(): array
{
    $timestamp = $this->getFakeTimestamp();

    return [
        'title' => $this->faker->sentence(),
        'body' => $this->faker->paragraph(),
        'more_inside' => $this->faker->paragraph(),
        'subsite_id' => Subsite::inRandomOrder()->first()->id,
        'user_id' => User::inRandomOrder()->first()->id,
        'created_at' => $timestamp,
        'published_at' => $timestamp,
        'updated_at' => null,
        'deleted_at' => null,
        'is_published' => true,
        'state' => PostStateEnum::Published->value,
    ];
}

方案2:用闭包延迟查询(更灵活)

public function definition(): array
{
    $timestamp = $this->getFakeTimestamp();

    return [
        'title' => $this->faker->sentence(),
        'body' => $this->faker->paragraph(),
        'more_inside' => $this->faker->paragraph(),
        'subsite_id' => fn () => Subsite::inRandomOrder()->first()->id,
        'user_id' => fn () => User::inRandomOrder()->first()->id,
        'created_at' => $timestamp,
        'published_at' => $timestamp,
        'updated_at' => null,
        'deleted_at' => null,
        'is_published' => true,
        'state' => PostStateEnum::Published->value,
    ];
}

方案3:预加载ID列表(性能更优)

如果需要生成大量数据,先一次性获取所有可用ID,后续随机选取,减少数据库查询次数:

class PostFactory extends Factory
{
    protected $model = Post::class;

    private array $subsiteIds;
    private array $userIds;

    public function __construct(Faker $faker)
    {
        parent::__construct($faker);
        $this->subsiteIds = Subsite::pluck('id')->toArray();
        $this->userIds = User::pluck('id')->toArray();
    }

    public function definition(): array
    {
        $timestamp = $this->getFakeTimestamp();

        return [
            'title' => $this->faker->sentence(),
            'body' => $this->faker->paragraph(),
            'more_inside' => $this->faker->paragraph(),
            'subsite_id' => $this->faker->randomElement($this->subsiteIds),
            'user_id' => $this->faker->randomElement($this->userIds),
            'created_at' => $timestamp,
            'published_at' => $timestamp,
            'updated_at' => null,
            'deleted_at' => null,
            'is_published' => true,
            'state' => PostStateEnum::Published->value,
        ];
    }
}

内容的提问来源于stack exchange,提问作者kirkaracha

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 00:55:09