我正在我的Laravel项目中编写一个命令,该命令将类别插入到数据库表中,但取决于它们是否已存在。
我调查了这样做的方法并遇到了<lvc:Axis.Separator>
<lvc:Separator StrokeThickness="1" />
</lvc:Axis.Separator>
方法,所以我在我的命令中写了以下内容:
firstOrCreate
基本上,我需要在communications_categories表中创建这两个类别,区域ID为1.作业更新类别已经存在,因此它按预期跳过了它,但是当它尝试创建没有这样做的警报类别时。存在我在控制台中收到以下错误:
SQLSTATE [23505]:唯一违规:7错误:重复键值 违反了唯一约束&#34; communications_categories_pkey&#34;
详细信息:Key(id)=(2)已存在。 (SQL:插入到 &#34; communications_categories&#34; (&#34;名称&#34;,&#34; region_id&#34;,&#34; updated_at&#34;, &#34; created_at&#34;)值(警报,1,2018-06-19 09:38:20,2018-06-19 09:38:20)返回&#34; id&#34;)
当它已经存在时,它似乎尝试分配主键ID为2 - 但是表结构在主键上有一个nextval,我认为这将添加最后一个ID并创建一个新的ID之后。根据关于Eloquent Inserts here的Laravel文档,没有提及必须规定实际的主键ID本身,并且可填充元素仅为$comCats = new CommunicationsCategories();
$comCats->firstOrCreate(
['name' => 'Job Updates'], ['region_id' => 1]);
$comCats->firstOrCreate(
['name' => 'Alerts'], ['region_id' => 1]);
和name
。< / p>
对此的任何帮助都表示赞赏,因为我对Laravel和eloqent数据库方法都相当新。如果有帮助,我会使用PostgreSQL数据库。
答案 0 :(得分:0)
firstOrCreate
方法将尝试使用给定的列/值对定位数据库记录。如果在数据库中找不到该模型,则将插入一条记录,其中包含第一个参数的属性以及可选的第二个参数中的属性。
$comCats->firstOrCreate(
['name' => 'Job Updates'], ['region_id' => 1]);
在这里,您尝试首先找到带有“作业更新”的name
和带有1的region_id
,如果laravel无法找到特定数据,它将尝试创建或插入给定参数,但是当系统尝试插入时,已存在值为“1”的region_id
。
如果region_id
是您的主键,请尝试:
$comCats->firstOrCreate(
['name' => 'Job Updates']);
答案 1 :(得分:0)
另一个答案似乎是假设您需要先向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
。
DB::insert($sql); // will return true
如果您需要返回Eloquent对象,建议使用returning *
或returning id
并将其传递给CommunicationsCategories::findOrFail($values[0]['id'])
。将复杂的insert语句放入Eloquent select中可能会花费很多工作。 Eloquent还具有一个称为hydr的函数,该函数无需其他SQL调用即可工作。
该SQL语句将插入所需的值,除非唯一约束存在冲突,然后它将通过更新将插入中从冲突中排除的值应用于先前存在的行。
答案 2 :(得分:0)
请原谅我还不能发表评论...
如果有人遇到关于 postgresql 的同样问题,这绝对是一个错误。在我的情况下,此错误发生在我按照以下过程使用 heroku 导入本地 postgresql 数据库之后:
Workaround for pushing to heroku database on windows machince.
我尝试再次运行查询,它奏效了……有时也会失败。现在这很糟糕。我会更新这个我找到了解决这个问题的另一种方法。
编辑: 在查看了有关该问题的更多搜索后,我发现以下内容与我的情况完全匹配:
PostgreSQL: Unique violation: 7 ERROR: duplicate key value violates unique constraint “users_pkey”