web-dev-qa-db-ja.com

Laravel移行ファイルにデータベースを追加する

私はただLaravelを学んでおり、ユーザーテーブルを作成する作業用の移行ファイルがあります。移行の一環としてユーザーレコードを作成しようとしています。

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

    });
}

しかし、php artisan migrateを実行すると、次のエラーが表示されます。

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

これは明らかに、Artisanがまだテーブルを作成していないためですが、すべてのドキュメントには、Fluent Queryを使用して移行の一部としてデータを取り込む方法があると言われているようです。

誰もが知っていますか?ありがとう!

92
Adam Hopkinson

DB :: insert()をSchema :: create()の中に入れないでください。なぜなら、ものを挿入する前にcreateメソッドがテーブルの作成を完了しなければならないからです。代わりにこれを試してください:

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

私はこれが古い投稿であることを知っていますが、グーグル検索で出てきたので、ここでいくつかの知識を共有すると思いました。 @ erin-geyerは、マイグレーションとシーダーを混在させると頭痛の種になる可能性があることを指摘し、@ justamartinは、デプロイメントの一部としてデータを取り込む必要がある場合があると反論しました。

さらに一歩進めて、データの変更を一貫して展開して、たとえばステージングに展開し、すべてが順調であることを確認してから、同じ結果を自信を持って本番に展開できるようにすることが望ましい場合があります(また、手動ステップを実行することを覚えておく必要はありません)。

ただし、シードと移行は2つの関連する別個の懸念事項であるため、これらを分離することには依然として価値があります。私たちのチームは、シーダーを呼び出す移行を作成することで妥協しました。これは次のようになります。

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

これにより、移行のようにシードを1回実行できます。動作を防止または強化するロジックを実装することもできます。例えば:

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

SomeModelが10個未満の場合、これは明らかに条件付きでシーダーを実行します。これは、artisan db:seedを呼び出したときに実行される標準のシーダーとして、また "ダブルアップ"しないように移行するときにシーダーを含める場合に便利です。ロールバックが期待どおりに機能するように、逆シーダーを作成することもできます。

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

2番目のパラメーター--forceは、実稼働環境でシーダーを実行できるようにするために必要です。

69
darrylkuhn

LaravelのDatabase Seederを使用する方がMigrationsを使用するよりも好ましい理由を非常によく説明しています。 http://laravelbook.com/laravel-database-seeding/

ただし、上記のリンクで説明されている実装は機能していないようで、不完全であるため、公式ドキュメントの指示に従う方がはるかに良い考えです。 http://laravel.com/docs/migrations#database-seeding

11
Erin Geyer

これはあなたが望むことをするはずです。

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

別のクリーンな方法は、インスタンスを作成し、関係するモデルを永続化するプライベートメソッドを定義することです。

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

このソリューションでは、タイムスタンプフィールドがEloquentによって生成されます。

編集:シーダーシステムを使用して、明確なデータベース構造の生成とデータベースの配置を行う方が適切です。

0

このDB挿入メソッドを試してみましたが、モデルを使用しないため、モデルにあったスラッグ可能な特性を無視しました。したがって、このテーブルのモデルが存在する場合、そのテーブルが移行されるとすぐに、モデルを使用してデータを挿入できるようになると考えました。そして、私はこれを思いつきました:

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

これは正常に機能し、モデルのスラグ可能な特性も考慮して、このエントリのスラッグを自動的に生成し、タイムスタンプも使用します。 NB。 IDの追加は必要ありませんでしたが、この例ではカテゴリに特定のIDが必要でした。 Laravel 5.8で動作確認済み

0
Andrew Arscott