php 在 Laravel 迁移文件中填充数据库

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12736120/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 04:06:57  来源:igfitidea点击:

Populating a database in a Laravel migration file

phplaravelmigrationmysql-error-1146

提问by Adam Hopkinson

I'm just learning Laravel, and have a working migration file creating a users table. I am trying to populate a user record as part of the migration:

我只是在学习 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
            )
        );

    });
}

But I'm getting the following error when running php artisan migrate:

但是我在运行时收到以下错误php artisan migrate

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

This is obviously because Artisan hasn't yet created the table, but all the documentation seems to say that there is a way of using Fluent Query to populate data as part of a migration.

这显然是因为 Artisan 还没有创建表,但所有文档似乎都说有一种方法可以使用 Fluent Query 来填充数据作为迁移的一部分。

Anyone know how? Thanks!

有谁知道怎么做?谢谢!

回答by BenjaminRH

Don't put the DB::insert() inside of the Schema::create(), because the create method has to finish making the table before you can insert stuff. Try this instead:

不要将 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
        )
    );
}

回答by darrylkuhn

I know this is an old post but since it comes up in a google search I thought I'd share some knowledge here. @erin-geyer pointed out that mixing migrations and seeders can create headaches and @justamartin countered that sometimes you want/need data to be populated as part of your deployment.

我知道这是一篇旧帖子,但由于它出现在谷歌搜索中,我想我会在这里分享一些知识。@erin-geyer 指出,混合迁移和播种器会让人头疼,@justamartin 反驳说,有时您希望/需要将数据作为部署的一部分进行填充。

I'd go one step further and say that sometimes it is desirable to be able to roll out data changes consistently so that you can for example deploy to staging, see that all is well, and then deploy to production with confidence of the same results (and not have to remember to run some manual step).

我更进一步说,有时希望能够始终如一地推出数据更改,这样您就可以例如部署到登台,看到一切都很好,然后在部署到生产时有信心获得相同的结果(并且不必记住运行一些手动步骤)。

However, there is still value in separating out the seed and the migration as those are two related but distinct concerns. Our team has compromised by creating migrations which call seeders. This looks like:

然而,分离种子和迁移仍然有价值,因为这是两个相关但不同的问题。我们的团队通过创建调用播种机的迁移来妥协。这看起来像:

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

This allows you to execute a seed one time just like a migration. You can also implement logic that prevents or augments behavior. For example:

这允许您像迁移一样执行一次种子。您还可以实现阻止或增强行为的逻辑。例如:

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

This would obviously conditionally execute your seeder if there are less than 10 SomeModels. This is useful if you want to include the seeder as a standard seeder that executed when you call artisan db:seedas well as when you migrate so that you don't "double up". You may also create a reverse seeder so that rollbacks works as expected, e.g.

如果 SomeModel 少于 10 个,这显然会有条件地执行您的播种器。如果您想将播种机作为标准播种机包含在调用artisan db:seed和迁移时执行的标准播种机中,这将非常有用,这样您就不会“加倍”。您还可以创建一个反向播种机,以便回滚按预期工作,例如

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

The second parameter --forceis required to enable to seeder to run in a production environment.

--force需要第二个参数才能使播种机在生产环境中运行。

回答by Erin Geyer

Here is a very good explanation of why using Laravel's Database Seeder is preferable to using Migrations: http://laravelbook.com/laravel-database-seeding/

这里很好地解释了为什么使用 Laravel 的 Database Seeder 比使用 Migrations 更可取:http://laravelbook.com/laravel-database-seeding/

Although, following the instructions on the official documentation is a much better idea because the implementation described at the above link doesn't seem to work and is incomplete. http://laravel.com/docs/migrations#database-seeding

虽然遵循官方文档中的说明是一个更好的主意,因为上述链接中描述的实现似乎不起作用并且不完整。 http://laravel.com/docs/migrations#database-seeding

回答by strings28

This should do what you want.

这应该做你想做的。

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

回答by Maximilien DI DIO

Another clean way to do it is to define a private method which create instance et persist concerned Model.

另一种干净的方法是定义一个私有方法,该方法创建实例和持久相关模型。

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

With this solution, timestamps fields will be generated by Eloquent.

使用此解决方案,Eloquent 将生成时间戳字段。

EDIT: it's better to use seeder system to disctinct database structure generation and database population.

编辑:最好使用播种系统来区分数据库结构生成和数据库填充。

回答by Andrew Arscott

I tried this DB insert method, but as it does not use the model, it ignored a sluggable trait I had on the model. So, given the Model for this table exists, as soon as its migrated, I figured the model would be available to use to insert data. And I came up with this:

我尝试了这个数据库插入方法,但由于它不使用模型,它忽略了我在模型上的一个sluggable 特性。因此,鉴于此表的模型存在,一旦迁移,我认为该模型可用于插入数据。我想出了这个:

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

This worked correctly, and also took into account the sluggable trait on my Model to automatically generate a slug for this entry, and uses the timestamps too. NB. Adding the ID was no neccesary, however, I wanted specific IDs for my categories in this example. Tested working on Laravel 5.8

这工作正常,并且还考虑了我的模型上的 sluggable 特征来自动为此条目生成一个 slug,并且也使用时间戳。注意。添加 ID 不是必需的,但是,在此示例中,我想要我的类别的特定 ID。在 Laravel 5.8 上测试

回答by CodeToLife

If you already have filled columns and have added new one or you want to fill out old column with new mock values , do this:

如果您已经填充了列并添加了新列,或者您想用新的模拟值填充旧列,请执行以下操作:

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