Laravel firstOrCreate 方法抛出重复 ID 错误

标签 laravel postgresql eloquent

我正在我的 Laravel 项目中编写一个命令,该命令将类别插入数据库表,但这取决于它们是否已经存在。

我调查了执行此操作的方法并遇到了 firstOrCreate 方法,因此我在命令中编写了以下内容:

$comCats = new CommunicationsCategories();

$comCats->firstOrCreate(
    ['name' => 'Job Updates'], ['region_id' => 1]);
$comCats->firstOrCreate(
    ['name' => 'Alerts'], ['region_id' => 1]);

基本上,我需要在区域 ID 为 1 的 communications_categories 表中创建这两个类别。Job Updates 类别已经存在,因此它按预期跳过了该类别,但是当它尝试创建不存在的 Alerts 类别时我的控制台出现以下错误:

SQLSTATE[23505]: Unique violation: 7 ERROR: duplicate key value violates unique constraint "communications_categories_pkey"

DETAIL: Key (id)=(2) already exists. (SQL: insert into "communications_categories" ("name", "region_id", "updated_at", "created_at") values (Alerts, 1, 2018-06-19 09:38:20, 2018-06-19 09:38:20) returning "id")

它似乎在尝试分配主键 ID 2(当它已经存在时)——但表结构在主键上有一个 nextval,我认为它会采用最后添加的 ID 并在之后创建一个新 ID。根据关于 Eloquent 插入的 Laravel 文档 here没有提到必须自己规定实际的主键id,可填充的元素只有nameregion_id

在此方面的任何帮助表示赞赏,因为我对 Laravel 和 Eloquent 数据库方法相当陌生。如果有帮助,我正在使用 PostgreSQL 数据库。

最佳答案

另一个答案似乎假定您需要向您解释 firstOrCreate,而实际上您实际上遇到了 Laravel 框架中的错误并且还假定 Key (id)=(2)region_id而不是你的自动递增主键 id .

您很可能希望在 communications_categories.name 上有一个唯一索引.

您可以在 postgres 中使用此 SQL(假设您在名称上有一个唯一索引),它应该比 firstOrCreate 更可靠,但是如果您打算将其他 laravel 功能与 firstOrCreate 一起使用(例如观察者或更多查询构建器) ,它们的功能可能会丢失。

    INSERT INTO communications_categories (name, region_id, created_at, updated_at)
    VALUES ('Job Updates', 1, NOW(), NOW())
    ON CONFLICT (name) DO
    UPDATE SET region_id = excluded.region_id,
        updated_at = NOW()
    RETURNING *;

可以这样使用:

    $values = DB::select($sql); // will return Array of StdClass

或没有returning *如果你不需要 id值(value)观。

    DB::insert($sql); // will return true

如果您需要返回 Eloquent 对象,我建议包括 returning *returning id并将其传递给 CommunicationsCategories::findOrFail($values[0]['id']) .将复杂的插入语句放入 Eloquent select 中可能需要大量工作。 Eloquent 还有一个名为 hydrate 的函数,无需额外的 SQL 调用即可工作。

SQL 语句将插入所需的值,除非在唯一约束上存在冲突,然后它将通过更新将被冲突排除的值从插入应用到预先存在的行。

关于Laravel firstOrCreate 方法抛出重复 ID 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50924236/

相关文章:

php - Laravel:helpers.php 第 531 行中的 ErrorException:

sql - 如何遍历查询结果

PHP 银条 ORM : Duplicate key value violates unique constraint for DataObject write

php - Laravel Eloquent - 如果列值为 NULL 或 0,则不运行关系查询

php - 使用 Laravel 获取记录时遇到问题

laravel - 如何将 HTML5 自定义 data-* 属性添加到 Laravel 4 Blade 模板?

php - 使用 Laravel 5 Eloquent 查询生成器的 DISTINCT 方法

php - 在 Laravel 中返​​回深度嵌套关系中的选定列

php - Laravel Eloquent ORM - 复杂的 where 查询

json - 使用 NULL 将 JSON 数组扩展为文本值