2012-10-03 40 views
77

¿Cómo podemos realizar inserciones de bases de datos masivas en Laravel con Eloquent ORM?Inserción masiva en Laravel con ORM elocuente

Quiero lograr esto en Laravel: https://stackoverflow.com/a/10615821/600516 pero recibo el siguiente error.

SQLSTATE [HY093]: Número de parámetro no válido: parámetros mixtos nombrados y posicionales.

+1

¿Tiene usted una relación 'HAS_MANY' en sus modelos? – PapaSmurf

+1

@jonathandey no, no tengo ninguna relación en este momento – phoenixwizard

+0

@DavidBarker He intentado formar la cadena quesr usando un ciclo for. También he intentado usar transacciones en laravel. – phoenixwizard

Respuesta

171

Puedes simplemente usar Eloquent::insert().

Por ejemplo:

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

Coder::insert($data); 
+115

Nota: esto no actualizará/creará marcas de tiempo. –

+2

¿Esto todavía se aplica a Laravel 4? – advait

+4

@advait: sí, todavía se aplica a Laravel 4. – Ola

42

Podemos actualizar respuesta GTF para actualizar fácilmente las marcas de tiempo

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

Actualización: para simplificar la fecha podemos utilizar carbón como @Pedro Moreira sugirió

$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: para laravel 5, use updated_at en su lugar o f 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); 
+34

O usa Carbon al comienzo de la secuencia de comandos para definir una variable '$ now':' $ now = Carbon: : ahora ('utc') -> toDateTimeString(); '. Entonces simplemente use ''created_at' => $ now, 'updated_at' => $ now' para cada inserción. –

+1

¿Cómo podemos obtener todas las ID de las filas recién insertadas? – akshaykumar6

+4

Se llama ** updated_at ** en Laravel 5. – Ben

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

UserSubscription es mi nombre del modelo. Esto devolverá "verdadero" si inserta con éxito else "falso".

13

Para quien esté leyendo esto, consulte 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; 
} 
+2

No publiques respuestas duplicadas en varias preguntas. Adapte su respuesta a la pregunta. – miken32

+11

@ miken32 Y ahí va la policía de stackoverflow;) Simplemente quería dejar una nota para googlers desesperados como yo, eso es todo. La respuesta es perfectamente autoexplicativa. – Alex

+2

Si quiere dejar una nota, hágalo como comentario. Las respuestas deben ser más de una oración con un enlace a algún código fuente. – miken32

6

Ésta es la forma de hacerlo de una manera más elocuente,

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

o cuando se utiliza fábricas de laravel (creación de 10 usuarios):

$users = factory(App\User::class, 10)->make()->toArray(); 

App\User::insert($users); 
-2

Quizás una manera más laravel para resolver este problema es usar una colección y colocarla en bucle insertándose con el modelo aprovechando las marcas de tiempo.

<?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:

Lo siento por mi mala interpretación. Para la inserción masiva esto podría ayudar y tal vez con esto puede hacer buenas sembradoras y optimizarlas un poco.

<?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); 
    } 
} 
+0

Esto hace una consulta por artículo. No es una inserción masiva. –

+1

@EmileBergeron Estoy de acuerdo contigo. He editado mi publicación así que tal vez esto podría ayudar a tener una buena inserción masiva. Si se dejan las tareas que toman mucho tiempo fuera del ciclo (carbono, bcript), esto puede ahorrarle mucho tiempo. –

0

me han buscado muchas veces para que, finalmente, se utiliza a medida timestamps, como a continuación:

$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], 
    .................................. 
]); 
Cuestiones relacionadas