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

Laravel7升级到8后执行db:seed报SQLSTATE[23000]错误怎么办?

问题根因

报错和你完成的Laravel 8 seeder适配操作无关,核心原因是DeliveryAddressTableSeeder中硬编码了主键id=1的固定数据,直接执行insert时数据库已经存在该主键的记录,触发主键唯一约束违反。

修复方案

方案1:本地测试环境清空目标表后再执行填充

如果是本地开发环境,不需要保留旧的测试数据,可先清空delivery_addresses表再跑seeder:

  • 执行 artisan 命令清空表:
    php artisan tinker --execute="DB::table('delivery_addresses')->truncate();"
  • 之后再运行php artisan db:seed即可。

方案2:修改seeder插入逻辑避免重复写入(推荐)

不需要清空现有数据的话,直接修改seeder的插入逻辑,使用updateOrInsert替代原生insert,存在同主键数据则更新,不存在则插入:
将原代码中的DeliveryAddress::insert($deliveryRecords);替换为:

foreach ($deliveryRecords as $record) {
    // 按主键id匹配,存在则更新,不存在则插入
    DeliveryAddress::updateOrInsert(['id' => $record['id']], $record);
}

如果不需要更新旧数据、仅插入不存在的记录,可使用以下逻辑:

foreach ($deliveryRecords as $record) {
    if (!DeliveryAddress::where('id', $record['id'])->exists()) {
        DeliveryAddress::create($record);
    }
}

注意:使用create方法需要确保App\DeliveryAddress模型的$fillable属性已包含上述所有字段,否则会触发批量赋值异常。

方案3:在seeder中内置清空表逻辑(仅适合测试环境)

如果你的seeder本身是用于生成固定基准测试数据,不需要保留旧数据,可在run()方法开头加清空表的逻辑:

public function run()
{
    // 清空表所有数据并重置自增ID
    DeliveryAddress::query()->truncate();

    $deliveryRecords = [
        // 原有数组保持不变
    ];

    DeliveryAddress::insert($deliveryRecords);
}

注意:truncate会删除表内全部数据,生产环境禁止使用。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.26 01:06:06