web-dev-qa-db-ja.com

雄弁なORMを使用したLaravelへの一括挿入

Eloquent ORMを使用してLaravelに一括データベース挿入を実行するにはどうすればよいですか?

私はLaravelでこれを達成したい: https://stackoverflow.com/a/10615821/600516 しかし、私は次のエラーを受け取っています。

SQLSTATE [HY093]:パラメーター番号が無効です:名前付きパラメーターと定位置パラメーターが混在しています。

119
phoenixwizard

Eloquent::insert()を使用できます。

例えば:

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

Coder::insert($data);
250
GTF

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

更新:日付を簡略化するために、@ 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: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);
63

これを読んでいる人は、 createMany() method をチェックしてください。

/**
 * 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;
}
23
Alex

これはあなたがより雄弁な方法でそれを行う方法です、

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

私はそれを何度も検索し、最終的に以下のようなカスタム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],
    ..................................
]);
3
srmilon

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

アイデアは、挿入を行う前に、配列全体にcreated_atとupdated_atを追加することです

1
sumit

カテゴリリレーションの挿入では、同じ問題に遭遇しましたが、私の雄弁なモデルでは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();
    }
}

「$ obj = new Self()」なしでは、単一のレコードのみを保存します($ objが$ thisの場合)

0
justnajm