php 使用 eloquent ORM 在 Laravel 中批量插入

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12702812/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 04:04:10  来源:igfitidea点击:

Bulk Insertion in Laravel using eloquent ORM

phpdatabaselaraveleloquent

提问by phoenixwizard

How can we perform bulk database insertions in Laravel using Eloquent ORM?

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

I want to accomplish this in Laravel: https://stackoverflow.com/a/10615821/600516but I am getting the following error.

我想在 Laravel 中完成此操作:https://stackoverflow.com/a/10615821/600516 但出现以下错误。

SQLSTATE[HY093]: Invalid parameter number: mixed named and positional parameters.

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

回答by GTF

You can just use Eloquent::insert().

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

For example:

例如:

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

Coder::insert($data);

回答by Eslam Salem Mahmoud

We can update GTF answer to update timestamps easily

我们可以更新 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);

Update: to simplify the date we can use carbon as @Pedro Moreira suggested

更新:为了简化日期,我们可以像@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);

UPDATE2: for laravel 5 , use updated_atinstead of modified_at

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);

回答by Alex

To whoever is reading this, check out createMany()method.

对于正在阅读本文的人,请查看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;
}

回答by imal hasaranga perera

This is how you do it in more Eloquent way,

这就是你如何以更雄辩的方式做到这一点,

    $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);

回答by srmilon

I searched many times for it, finally used custom timestampslike below:

我搜索了很多次,最后使用了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],
    ..................................
]);

回答by sumit

Eloquent::insertis the proper solution but it wont update the timestamps, so you can do something like below

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);

The idea is to add created_at and updated_at on whole array before doing insert

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

回答by Walid Natat

From Laravel 5.7 with Illuminate\Database\Query\Builderyou can use insertUsing method.

从 Laravel 5.7 开始,Illuminate\Database\Query\Builder您可以使用 insertUsing 方法。

$query = [];
foreach($oXML->results->item->item as $oEntry){
    $date = date("Y-m-d H:i:s")
    $query[] = "('{$oEntry->firstname}', '{$oEntry->lastname}', '{$date}')";
}

Builder::insertUsing(['first_name', 'last_name', 'date_added'], implode(', ', $query));

回答by justnajm

For category relations insertion I came across the same problem and had no idea, except that in my eloquent model I used Self() to have an instance of the same class in foreach to record multiple saves and grabing ids.

对于类别关系插入,我遇到了同样的问题并且不知道,除了在我雄辩的模型中我使用 Self() 在 foreach 中有一个相同类的实例来记录多个保存和抓取 id。

foreach($arCategories as $v)
{                
    if($v>0){
        $obj = new Self(); // this is to have new instance of own
        $obj->page_id = $page_id;
        $obj->category_id = $v;
        $obj->save();
    }
}

without "$obj = new Self()" it only saves single record (when $obj was $this)

没有 "$obj = new Self()" 它只保存单条记录(当 $obj 是 $this 时)

回答by Francisco Daniel

Maybe a more Laravel way to solve this problem is to use a collection and loop it inserting with the model taking advantage of the timestamps.

也许更 Laravel 解决这个问题的方法是使用一个集合并利用时间戳循环将其插入模型。

<?php

use App\Continent;
use Illuminate\Database\Seeder;

class InitialSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        collect([
            ['name' => 'América'],
            ['name' => 'áfrica'],
            ['name' => 'Europa'],
            ['name' => 'Asia'],
            ['name' => 'Oceanía'],
        ])->each(function ($item, $key) {
            Continent::forceCreate($item);
        });
    }
}

EDIT:

编辑:

Sorry for my misunderstanding. For bulk inserting this could help and maybe with this you can make good seeders and optimize them a bit.

对不起,我的误解。对于批量插入,这可能会有所帮助,也许有了这个,您可以制作好的播种机并对其进行一些优化。

<?php

use App\Continent;
use Carbon\Carbon;
use Illuminate\Database\Seeder;

class InitialSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        $timestamp = Carbon::now();
        $password = bcrypt('secret');

        $continents = [
            [
                'name' => 'América'
                'password' => $password,
                'created_at' => $timestamp,
                'updated_at' => $timestamp,
            ],
            [
                'name' => 'áfrica'
                'password' => $password,
                'created_at' => $timestamp,
                'updated_at' => $timestamp,
            ],
            [
                'name' => 'Europa'
                'password' => $password,
                'created_at' => $timestamp,
                'updated_at' => $timestamp,
            ],
            [
                'name' => 'Asia'
                'password' => $password,
                'created_at' => $timestamp,
                'updated_at' => $timestamp,
            ],
            [
                'name' => 'Oceanía'
                'password' => $password,
                'created_at' => $timestamp,
                'updated_at' => $timestamp,
            ],
        ];

        Continent::insert($continents);
    }
}

回答by Nikunj K.

$start_date = date('Y-m-d h:m:s');        
        $end_date = date('Y-m-d h:m:s', strtotime($start_date . "+".$userSubscription['duration']." months") );
        $user_subscription_array = array(
          array(
            'user_id' => $request->input('user_id'),
            'user_subscription_plan_id' => $request->input('subscription_plan_id'),
            'name' => $userSubscription['name'],
            'description' => $userSubscription['description'],
            'duration' => $userSubscription['duration'],
            'start_datetime' => $start_date,
            'end_datetime' => $end_date,
            'amount' => $userSubscription['amount'],
            'invoice_id' => '',
            'transection_datetime' => '',
            'created_by' => '1',
            'status_id' => '1', ),
array(
            'user_id' => $request->input('user_id'),
            'user_subscription_plan_id' => $request->input('subscription_plan_id'),
            'name' => $userSubscription['name'],
            'description' => $userSubscription['description'],
            'duration' => $userSubscription['duration'],
            'start_datetime' => $start_date,
            'end_datetime' => $end_date,
            'amount' => $userSubscription['amount'],
            'invoice_id' => '',
            'transection_datetime' => '',
            'created_by' => '1',
            'status_id' => '1', )
        );
        dd(UserSubscription::insert($user_subscription_array));

UserSubscriptionis my model name. This will return "true" if insert successfully else "false".

UserSubscription是我的模特名字。如果插入成功,这将返回“true”,否则返回“false”。