使用雄辩的ORM在Laravel中批量插入

pho*_*ard 135 php database laravel eloquent

我们如何使用Eloquent ORM在Laravel中执行批量数据库插入?

我想在Laravel中完成此任务:https://stackoverflow.com/a/10615821/600516 但我收到以下错误.

SQLSTATE [HY093]:参数号无效:混合命名和位置参数.

GTF*_*GTF 270

你可以使用Eloquent::insert().

例如:

$data = array(
    array('name'=>'Coder 1', 'rep'=>'4096'),
    array('name'=>'Coder 2', 'rep'=>'2048'),
    //...
);

Coder::insert($data);
Run Code Online (Sandbox Code Playgroud)

  • 注意:这不会更新/创建时间戳. (165认同)
  • 值得注意的是,它实际上并没有触及"雄辩".它只是代理调用`Query\Builder @ insert()`方法.没有办法用Eloquent有效地插入多行,也没有为批量插入提供任何方法. (26认同)
  • @CanVural我们应该怎样做才能更新/创建时间戳? (6认同)
  • @advait:是的,它仍然适用于Laravel 4. (4认同)
  • 这仍然适用于Laravel 4吗? (2认同)
  • 我们如何获取新插入行的所有 ID? (2认同)
  • 这将使用一个插入.所以,给定一个足够大的数组,它将失败. (2认同)
  • @JarekTkaczyk是对的,这使得基于模型的调用成为一种误导性的抽象,因为它绕过了诸如$ fillable和模型事件(如创建,创建......)之类的事情.这一切都被忽略了. (2认同)
  • @SagarAhuja我只是尝试了同样的操作,它不会自动插入“created_at”和“updated_at”值 - 也许您手动设置它们。 (2认同)

小智 69

我们可以更新GTF答案以轻松更新时间戳

$data = array(
    array(
        'name'=>'Coder 1', 'rep'=>'4096',
        'created_at'=>date('Y-m-d H:i:s'),
        'modified_at'=> date('Y-m-d H:i:s')
       ),
    array(
         'name'=>'Coder 2', 'rep'=>'2048',
         'created_at'=>date('Y-m-d H:i:s'),
         'modified_at'=> date('Y-m-d H:i:s')
       ),
    //...
);

Coder::insert($data);
Run Code Online (Sandbox Code Playgroud)

更新:为了简化我们可以使用碳的日期,@ Pedro Moreira建议

$now = Carbon::now('utc')->toDateTimeString();
$data = array(
    array(
        'name'=>'Coder 1', 'rep'=>'4096',
        'created_at'=> $now,
        'modified_at'=> $now
       ),
    array(
         'name'=>'Coder 2', 'rep'=>'2048',
         'created_at'=> $now,
         'modified_at'=> $now
       ),
    //...
);

Coder::insert($data);
Run Code Online (Sandbox Code Playgroud)

UPDATE2:对于laravel 5,使用updated_at而不是modified_at

$now = Carbon::now('utc')->toDateTimeString();
$data = array(
    array(
        'name'=>'Coder 1', 'rep'=>'4096',
        'created_at'=> $now,
        'updated_at'=> $now
       ),
    array(
         'name'=>'Coder 2', 'rep'=>'2048',
         'created_at'=> $now,
         'updated_at'=> $now
       ),
    //...
);

Coder::insert($data);
Run Code Online (Sandbox Code Playgroud)

  • 或者在脚本开头使用Carbon来定义`$ now`变量:`$ now = Carbon :: now('utc') - > toDateTimeString();`.然后只需使用''created_at'=> $ now,'updated_at'=> $ now`进行每次插入. (41认同)
  • 它在Laravel 5中被称为**updated_at**. (5认同)
  • 我不想开始一个巨大的"空格与标签"参数,但请保存UTC时间戳!它会在以后为您节省大量的痛苦!想想全球用户:) (5认同)
  • 如果我问,在这种情况下对“碳”的最大需求是什么?`date("Ymd H:i:s")` 有什么问题? (3认同)
  • 我们如何获取新插入行的所有 ID? (2认同)
  • 为什么'utc'?是项目的优先权,还是,雄辩的说服总是在'utc'工作? (2认同)

Ale*_*lex 27

对于正在阅读本文的人,请查看createMany()方法.

/**
 * Create a Collection of new instances of the related model.
 *
 * @param  array  $records
 * @return \Illuminate\Database\Eloquent\Collection
 */
public function createMany(array $records)
{
    $instances = $this->related->newCollection();

    foreach ($records as $record) {
        $instances->push($this->create($record));
    }

    return $instances;
}
Run Code Online (Sandbox Code Playgroud)

  • @ miken32那里有堆栈溢流警察;)我只是想为像我这样的绝望的谷歌留下一张便条,就是这样.答案是完全不言自明的. (31认同)
  • 这不是所谓的批量插入.由于实现不佳,此函数将为每个项目准备和执行相同的查询一次. (18认同)
  • @ miken32我不同意.一行答案可以很好.这取决于问题.如果您不喜欢该表格,请随时编辑答案. (7认同)
  • 值得注意的是,这是一个关系方法,不能直接从模型调用,即“Model::createMany()”。 (3认同)
  • 请不要在多个问题上发布重复的答案.定制你对这个问题的回答. (2认同)
  • 如果您想留言,请将其作为评论.答案需要不止一个句子,并带有一些源代码的链接. (2认同)

ima*_*era 17

这是你如何以更有说服力的方式做到这一点,

    $allintests = [];
    foreach($intersts as $item){ //$intersts array contains input data
        $intestcat = new User_Category();
        $intestcat->memberid = $item->memberid;
        $intestcat->catid= $item->catid;
        $allintests[] = $intestcat->attributesToArray();
    }
    User_Category::insert($allintests);
Run Code Online (Sandbox Code Playgroud)


小智 9

我搜索了很多次,最后使用了timestamps如下自定义:

$now = Carbon::now()->toDateTimeString();
Model::insert([
    ['name'=>'Foo', 'created_at'=>$now, 'updated_at'=>$now],
    ['name'=>'Bar', 'created_at'=>$now, 'updated_at'=>$now],
    ['name'=>'Baz', 'created_at'=>$now, 'updated_at'=>$now],
    ..................................
]);
Run Code Online (Sandbox Code Playgroud)


sum*_*mit 6

Eloquent::insert是正确的解决方案,但它不会更新时间戳,因此您可以执行如下操作

 $json_array=array_map(function ($a) { 
                        return array_merge($a,['created_at'=> 
                                            Carbon::now(),'updated_at'=> Carbon::now()]
                                           ); 
                                     }, $json_array); 
 Model::insert($json_array);
Run Code Online (Sandbox Code Playgroud)

这个想法是在执行插入之前在整个数组上添加created_at和updated_at