【问题标题】:Eloquent updateOrCreate() overwrites all rows - trying to understand it雄辩的 updateOrCreate() 覆盖所有行 - 试图理解它
【发布时间】:2017-11-05 15:27:56
【问题描述】:

我在理解 updateOrCreate Eloquent 方法时遇到问题。

我有一个简单的数据库,我在其中保存来自 API 的信息并每 x 分钟运行一次。

如果数据库中不存在该行,我需要执行 INSERT,否则只需执行 UPDATE 并更新更改的数据。

我们如何在 Laravel 中实现这个功能?

这就是我现在所拥有的,但它会在所有行中重写相同的数据。

不确定我是否理解正确。

我基本上是在传递一个“条件”,即。需要检查它们是否唯一的字段-campaign_id+variation_id 应该是唯一的。 (它由 MySQL 中的 UNIQUE 键支持)和我的数据数组:

$data = [
    'campaign_id' => $variation['campaign_id'],
    'variation_id' => $variation['variation_id'],
    'name' => $variation['name'],
    'description' => $variation['description'],
];

MyModel::updateOrCreate( ['campaign_id' => $variation['campaign_id'], 'variation_id' => 
$variation['variation_id'] ], $data);

它似乎与 updateOrInsert 一起工作,这是一种查询生成器方法,但我想用 Eloquent 实现这一点,认为这很容易。 Plus Query Builder 不会为我填写时间戳。

感谢任何提示!

【问题讨论】:

  • 您是否在模型中设置了受保护的 $primaryKey 属性?
  • 是的,它实际上设置为。受保护的 $primaryKey = 'campaign_id';它会引起一些问题吗?

标签: mysql laravel eloquent laravel-eloquent


【解决方案1】:

看Laravel的源码,updateOrCreate()在水下使用firstOrNew($attributes)。

public function updateOrCreate(array $attributes, array $values = [])
{
    return tap($this->firstOrNew($attributes), function ($instance) use ($values) {
        $instance->fill($values)->save();
    });
}

Source

所以当基于$attributes找到1个或多个项目时,它只会更新那些匹配项目的第一个结果。

记录您的所有查询并检查您的代码实际在做什么。 Logging queries

使用 updateOrCreate() 应该会产生 1 个选择和 1 个更新或插入查询,因此总共有 2 个。

【讨论】:

  • select * from variations where (campaign_id = ? and variation_id = ?) limit 1" "update variations set name = ?, description = ?, @ 987654336@ = ? campaign_id = 哪里? ....它省略了 AND variaiton_id = ?健康)状况。不知道为什么。
  • 然后@fmgonzalez 的评论适用。你已经将 primaryKey 设置为campaign_id,所以 Laravel 期望它是一个唯一的值。因此,如果它找到 1,则假定campaign_id 是该模型的唯一标识符,并从更新查询中省略其余部分。你需要的是复合主键,见stackoverflow.com/questions/31415213/…
  • 使用复合键解决了问题。我必须加载包github.com/mopo922/LaravelTreats/tree/master/src/Model,它现在可以工作了。
【解决方案2】:

所以是的,我有这种感觉,@Robert 给了你证据。

您只需通过这种方式将模型的$primaryKey 设置为复合值:

protected $primarykey = ['campaign_id', 'variation_id']; 

我希望它对你有用。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2023-03-10
  • 2014-07-23
  • 2012-12-17
  • 2020-09-20
  • 2020-07-18
  • 1970-01-01
  • 2016-06-27
  • 1970-01-01
相关资源
最近更新 更多