165 votes

Remplissage d'une base de données dans un fichier de migration Laravel

Je viens d'apprendre Laravel, et j'ai un fichier de migration fonctionnel qui crée une table d'utilisateurs. J'essaie de remplir un enregistrement d'utilisateur dans le cadre de la migration :

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' => 'name@domain.com',
                'verified' => true
            )
        );

    });
}

Mais j'obtiens l'erreur suivante lors de l'exécution php artisan migrate :

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

C'est évidemment parce qu'Artisan n'a pas encore créé la table, mais toute la documentation semble dire qu'il existe un moyen d'utiliser Fluent Query pour alimenter les données dans le cadre d'une migration.

Quelqu'un sait comment ? Merci.

295voto

BenjaminRH Points 4540

Ne placez pas DB::insert() à l'intérieur de Schema::create(), car la méthode de création doit terminer la création de la table avant que vous puissiez insérer des données. Essayez plutôt ceci :

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' => 'name@domain.com',
            'verified' => true
        )
    );
}

106voto

darrylkuhn Points 1150

Je sais que c'est un vieux post mais comme il apparaît dans une recherche google, j'ai pensé partager quelques connaissances ici. @erin-geyer a souligné que le mélange des migrations et des semoirs peut créer des maux de tête et @justamartin a contré que parfois vous voulez / avez besoin que les données soient alimentées dans le cadre de votre déploiement.

J'irais même plus loin en disant qu'il est parfois souhaitable de pouvoir déployer les changements de données de manière cohérente, de sorte que vous puissiez, par exemple, effectuer un déploiement dans une base de données, voir que tout va bien, puis effectuer un déploiement dans la production en étant sûr d'obtenir les mêmes résultats (sans avoir à vous souvenir d'exécuter une étape manuelle).

Cependant, il est toujours utile de séparer les semences et la migration, car il s'agit de deux problèmes liés mais distincts. Notre équipe a fait un compromis en créant des migrations qui appellent des seeders. Cela ressemble à cela :

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

Cela vous permet d'exécuter une graine une seule fois, tout comme une migration. Vous pouvez également mettre en œuvre une logique qui empêche ou augmente le comportement. Par exemple :

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

Cela permettrait évidemment d'exécuter conditionnellement votre seeder s'il y a moins de 10 SomeModels. Ceci est utile si vous voulez inclure le seeder comme un seeder standard qui s'exécute lorsque vous appelez artisan db:seed ainsi que lorsque vous migrez, afin d'éviter de faire double emploi. Vous pouvez également créer un reverse seeder pour que les rollbacks fonctionnent comme prévu, par ex.

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

Le deuxième paramètre --force est nécessaire pour permettre au seeder de fonctionner dans un environnement de production.

19voto

Erin Geyer Points 161

Voici une très bonne explication de la raison pour laquelle l'utilisation de Database Seeder de Laravel est préférable à l'utilisation de Migrations : https://web.archive.org/web/20171018135835/http://laravelbook.com/laravel-database-seeding/

Cependant, suivre les instructions de la documentation officielle est une bien meilleure idée, car l'implémentation décrite dans le lien ci-dessus ne semble pas fonctionner et est incomplète. http://laravel.com/docs/migrations#database-seeding

8voto

Martin Mbae Points 535

Si vous utilisez Laravel 8 et souhaitez initialiser avec multiple vous pouvez le faire de l'une de ces deux façons.

1. La méthode non recommandée

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',
                ],
            )
        );
    }

La méthode ci-dessus est bonne, mais elle laissera l créé_at y updated_at colonnes vides.

2. La voie recommandée

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

    }

5voto

strings28 Points 158

Cela devrait faire ce que vous voulez.

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X