2012-10-04 41 views
48

Ich lerne gerade Laravel und habe eine funktionierende Migrationsdatei, die eine Benutzertabelle erstellt. Ich versuche, einen Benutzerdatensatz als Teil der Migration zu füllen:Füllen einer Datenbank in einer Laravel-Migrationsdatei

public function up() 
{ 
    Schema::create('users', function($table){ 

     $table->increments('id'); 
     $table->string('email', 255); 
     $table->string('password', 64); 
     $table->boolean('verified'); 
     $table->string('token', 255); 
     $table->timestamps(); 

     DB::table('users')->insert(
      array(
       'email' => '[email protected]', 
       'verified' => true 
      ) 
     ); 

    }); 
} 

Aber ich erhalte die folgende Fehlermeldung, wenn php artisan migrate ausgeführt wird:

SQLSTATE[42S02]: Base table or view not found: 1146 Table 'vantage.users' doesn't exist 

Dies ist offensichtlich, da Artisan wurde noch nicht erstellt die Tabelle, aber die gesamte Dokumentation scheint zu sagen, dass es eine Möglichkeit gibt, Fluent Query zu verwenden, um Daten als Teil einer Migration zu füllen.

Wer weiß wie? Vielen Dank!

Antwort

115

Stellen Sie die DB nicht :: insert() innerhalb des Schemas :: create(), weil die create-Methode, bevor Sie den Tisch zu beenden hat kann Zeug einfügen. Versuchen Sie dies stattdessen:

public function up() 
{ 
    // Create the table 
    Schema::create('users', function($table){ 
     $table->increments('id'); 
     $table->string('email', 255); 
     $table->string('password', 64); 
     $table->boolean('verified'); 
     $table->string('token', 255); 
     $table->timestamps(); 
    }); 

    // Insert some stuff 
    DB::table('users')->insert(
     array(
      'email' => '[email protected]', 
      'verified' => true 
     ) 
    ); 
} 
+0

Danke Benjamin, das ist ausgezeichnet! –

+0

und wie Sie mehrere Daten einfügen? –

-4

Versuch: (nicht getestet)

public function up() 
{ 
    Schema::table('users', function($table){ 

     $table->increments('id'); 
     $table->string('email', 255); 
     $table->string('password', 64); 
     $table->boolean('verified'); 
     $table->string('token', 255); 
     $table->timestamps(); 

     $table->insert(
      array(
       'email' => '[email protected]', 
       'verified' => true 
      ) 
     ); 

    }); 
} 
+0

Danke @ aowie1 - Ich hatte das schon versucht, aber es ist fehlerhaft, weil 'Table :: insert()' keine gültige Methode ist –

1

Dies sollte tun, was Sie wollen.

public function up() 
{ 
    DB::table('user')->insert(array('username'=>'dude', 'password'=>'z19pers!')); 
} 
+0

Danke @ strings28, aber hast du gesehen, dass ich schon vor einem Monat eine ähnliche Antwort akzeptiert habe? –

+0

Anscheinend habe ich nicht - sorry :) – strings28

9

ist hier eine sehr gute Erklärung, warum mit Laravel der Datenbank Seeder vorzuziehen mit Migrations: eine viel bessere Idee http://laravelbook.com/laravel-database-seeding/

Obwohl nach den Anweisungen auf der offiziellen Dokumentation, weil die Umsetzung auf die beschriebene Der obige Link scheint nicht zu funktionieren und ist unvollständig. http://laravel.com/docs/migrations#database-seeding

+1

Ich stimme dir zu Erin. Mischen Sie keine Migrationen mit Seed-Daten, da es sehr wahrscheinlich ist, dass Sie einige Daten in Ihrer Entwicklungsumgebung, nicht jedoch in Ihrer Produktionsumgebung bereitstellen möchten. –

+10

Guter Punkt, aber es gibt einige Situationen, in denen einige Daten in der Produktionsumgebung vorhanden sein müssen. Beispielsweise muss der allererste Standardadministratorbenutzer vorhanden sein, damit sich der Kunde zum ersten Mal anmelden kann. Einige voreingestellte Berechtigungsrollen müssen vorhanden sein, einige Geschäftslogikdaten können auch sofort erforderlich sein. Daher denke ich, dass obligatorische Daten zu Migrationen hinzugefügt werden sollten (so dass Sie auch Datensätze durch separate Migrationen hoch/runter gehen können), aber Samen können für die Entwicklung belassen werden. – JustAMartin

+0

Eine kleine Notiz; Der Link zur Datenbank-Seeding ist jetzt: https://laravel.com/docs/5.3/seeding – magikMaker

42

Ich weiß, dies ist ein alter Post, aber da es in einer Google-Suche kommt, dachte ich, ich würde hier etwas Wissen teilen. @ erin-geyer wies darauf hin, dass das Mischen von Migrationen und Seedern Kopfschmerzen bereiten kann, und @justamartin entgegnete, dass Daten, die Sie benötigen, manchmal als Teil Ihrer Bereitstellung ausgefüllt werden müssen. Ich würde noch einen Schritt weiter gehen und sagen, dass es manchmal wünschenswert ist, Datenänderungen konsistent ausrollen zu können, so dass Sie zum Beispiel ins Staging implementieren können, dass alles in Ordnung ist, und dann sicher in der Produktion bereitstellen können der gleichen Ergebnisse (und nicht daran denken, einen manuellen Schritt auszuführen).

Es gibt jedoch immer noch einen Wert bei der Trennung von Saatgut und Migration, da dies zwei verwandte, aber unterschiedliche Probleme sind. Unser Team hat sich kompromittiert, indem es Migrationen erstellt hat, die Sämaschinen aufrufen. Das sieht so aus:

public function up() 
{ 
    Artisan::call('db:seed', [ 
     '--class' => 'SomeSeeder', 
     '--force' => true ] 
    ); 
} 

Dies ermöglicht es Ihnen, einen Samen genau wie eine Migration einmal auszuführen. Sie können auch eine Logik implementieren, die das Verhalten verhindert oder erweitert. Zum Beispiel:

public function up() 
{ 
    if (SomeModel::count() < 10) 
    { 
     Artisan::call('db:seed', [ 
      '--class' => 'SomeSeeder', 
      '--force' => true ] 
     ); 
    } 
} 

Dies würde ausführen offensichtlich bedingt Ihre seeder, wenn es weniger als 10 SomeModels. Dies ist nützlich, wenn Sie den Seeder als Standard-Seeder einfügen möchten, der ausgeführt wird, wenn Sie artisan db:seed aufrufen, sowie wenn Sie migrieren, damit Sie nicht "verdoppeln". Sie können auch eine umgekehrte Sämaschine erstellen, damit Rollbacks wie erwartet ausgeführt werden, z.

public function down() 
{ 
    Artisan::call('db:seed', [ 
     '--class' => 'ReverseSomeSeeder', 
     '--force' => true ] 
    ); 
} 

Der zweite Parameter ist erforderlich, um --force Einzelkornsämaschine zu ermöglichen, in einer Produktionsumgebung zu laufen.

+1

Dies ist bei weitem die beste Antwort. Wartbarer Code, der Probleme trennt! – helsont

+3

Ich würde die langfristigen Auswirkungen des Aufrufs von Seedern aus Migrationsskripten berücksichtigen. Die Migrationsskripts sind mit Datum/Uhrzeit versioniert, während dies normalerweise nicht der Fall ist. Während der Entwicklung müssen sich die Seeder-Anforderungen häufig ändern. Dies kann dazu führen, dass versionierte Migrationsskripts nicht-versionierte Seeder ausführen können, wodurch die Idempotenz aufgehoben wird. Mit anderen Worten, das Ausführen derselben Migrationsskripts von Tag zu Tag kann zu unterschiedlichen Ergebnissen führen. – originalbryan

+0

Es ist schon eine Weile her, seit ich das geschrieben habe und ich wollte unsere Erfahrung mit dieser Technik zur Verfügung stellen. Insgesamt hat es für uns gut funktioniert und wenn ich es nochmal machen müsste, würde ich es tun. Das heißt, es gibt ein Problem zu beachten. @originalbryan ist genau richtig und die Konsequenz ist, dass wir gelegentlich in Situationen geraten, in denen Migrationen brechen, wenn eine frische DB gestartet wird, weil die Sämaschine (und das Modell) aktueller sind als die Datenbank (da wir vielleicht säen) bevor das Schema vollständig aktualisiert wird). In diesem Fall aktualisieren wir die alte Migration, um das Problem zu beheben. – darrylkuhn

Verwandte Themen