Een database vullen in een Laravel-migratiebestand

Ik ben net Laravel aan het leren en heb een werkend migratiebestand dat een gebruikerstabel maakt. Ik probeer een gebruikersrecord in te vullen als onderdeel van de migratie:

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

Maar ik krijg de volgende foutmelding bij het uitvoeren van php artisan migrate:

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

Dit is duidelijk omdat Artisan de tabel nog niet heeft gemaakt, maar alle documentatie lijkt te zeggen dat er een manier is om Fluent Query te gebruiken om gegevens te vullen als onderdeel van een migratie.

Weet iemand hoe? Bedankt!


Antwoord 1, autoriteit 100%

Plaats de DB::insert() niet in het Schema::create(), omdat de create-methode eerst de tabel moet maken voordat je dingen kunt invoegen. Probeer in plaats daarvan dit:

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

Antwoord 2, autoriteit 37%

Ik weet dat dit een oud bericht is, maar aangezien het in een Google-zoekopdracht naar voren komt, dacht ik dat ik hier wat kennis zou delen. @erin-geyer wees erop dat het mixen van migraties en seeders hoofdpijn kan veroorzaken en @justamartin wierp tegen dat u soms wilt/moet dat gegevens worden ingevuld als onderdeel van uw implementatie.

Ik zou nog een stap verder willen gaan en zeggen dat het soms wenselijk is om gegevenswijzigingen consistent uit te kunnen rollen, zodat u bijvoorbeeld kunt implementeren in staging, kunt zien of alles in orde is en vervolgens met vertrouwen kunt implementeren in productie. dezelfde resultaten (en niet te onthouden om een ​​handmatige stap uit te voeren).

Het is echter nog steeds waardevol om het zaad en de migratie te scheiden, aangezien dit twee gerelateerde maar verschillende zorgen zijn. Ons team heeft gecompromitteerd door migraties te maken die seeders aanroepen. Dit ziet er als volgt uit:

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

Hierdoor kunt u een seed eenmalig uitvoeren, net als bij een migratie. U kunt ook logica implementeren die gedrag voorkomt of verbetert. Bijvoorbeeld:

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

Dit zou uiteraard uw seeder voorwaardelijk uitvoeren als er minder dan 10 SomeModels zijn. Dit is handig als u de seeder wilt opnemen als een standaard seeder die wordt uitgevoerd wanneer u artisan db:seedaanroept en ook wanneer u migreert, zodat u niet “verdubbelt”. U kunt ook een reverse seeder maken, zodat rollbacks werken zoals verwacht, bijvoorbeeld

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

De tweede parameter --forceis vereist om in te schakelen om in een productieomgeving te lopen.


Antwoord 3, Autoriteit 6%

Hier is een zeer goede uitleg waarom het gebruik van de databasezaaimachine van Laravel de voorkeur heeft bij het gebruik van migraties: https://web.archive.org/web/20171018135835/HTTP://laravelbook.com/laravel-database-seeding/

Hoewel, na de instructies over de officiële documentatie een veel beter idee is, omdat de implementatie die wordt beschreven op de bovenstaande link niet lijkt te werken en onvolledig is. http://laravel.com/docs/migraties#Database-seeding


Antwoord 4, Autoriteit 3%

Als u Laravel 8 gebruikt en zou willen initialiseren met meerdere records die u op een van deze twee manieren kunt doen.

1. De niet-aanbevolen manier

public function up()
    {
        Schema::create('categories', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->timestamps();
        });
        DB::table('categories')->insert(
            array(
                [
                    'name' => 'Category1',
                ],
                [
                    'name' => 'Category2',
                ],
                [
                    'name' => 'Category3',
                ],
            )
        );
    }

De bovenstaande methode is prima, maar laat de gemaakt_at en bijgewerkte_at kolommen leeg.

2. De aanbevolen manier

public function up()
    {
        Schema::create('categories', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->timestamps();
        });
        $data =  array(
            [
                'name' => 'Category1',
            ],
            [
                'name' => 'Category2',
            ],
            [
                'name' => 'Category3',
            ],
        );
        foreach ($data as $datum){
            $category = new Category(); //The Category is the model for your migration
            $category->name =$datum['name'];
            $category->save();
        }
    }

Antwoord 5, Autoriteit 2%

Dit zou moeten doen wat u wilt.

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

Antwoord 6

Nog een schone manier om het te doen, is om een ​​privé-methode te definiëren die exemplaar is dat ET Personage Model is.

public function up()
{
    Schema::create('roles', function (Blueprint $table) {
        $table->increments('id');
        $table->string('label', 256);
        $table->timestamps();
        $table->softDeletes();
    });
    $this->postCreate('admin', 'user');
}
private function postCreate(string ...$roles)  {
    foreach ($roles as $role) {
        $model = new Role();
        $model->setAttribute('label', $role);
        $model->save();
    }
}

Met deze oplossing worden tijdstempelvelden gegenereerd door welsprekend.

EDIT:
Het is beter om zaaimesysteem te gebruiken voor gedetineerde database-structuuropwekking en databasepopulatie.


Antwoord 7

Ik heb deze DB-insert-methode geprobeerd, maar omdat het het model niet gebruikt, negeerde het een roerbare eigenschap die ik op het model had. Dus, gezien het model voor deze tabel bestaat, zodra het gemigreerd is, dacht ik dat het model beschikbaar zou zijn om gegevens in te voegen. En ik kwam hier bij:

public function up() {
        Schema::create('parent_categories', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('name');
            $table->string('slug');
            $table->timestamps();
        });
        ParentCategory::create(
            [
                'id' => 1,
                'name' => 'Occasions',
            ],
        );
    }

Dit werkte correct, en hield ook rekening met de roozelige eigenschap op mijn model om automatisch een slak voor dit item te genereren en ook de tijdstempels gebruikt.
NB. Het toevoegen van de ID was niet nodig, maar ik wilde echter specifieke ID’s voor mijn categorieën in dit voorbeeld.
Getest op Laravel 5.8


Antwoord 8

Als u al kolommen hebt gevuld en nieuwe hebt toegevoegd of u oude kolom wilt invullen met nieuwe mockwaarden, doe dit dan:

public function up()
{
    DB::table('foydabars')->update(
        array(
            'status' => '0'
        )
    );
}

Other episodes