Laravel : 生产数据的迁移和播种

我的应用程序需要预先注册的数据集才能正常工作。因此,当我设置应用程序时,我需要将它们插入到数据库中。

Laravel提出了两种机制:

  • 数据库迁移“它们允许团队修改数据库架构并保持当前架构状态的最新状态。
  • 数据库种子设定:“Laravel还包括一种使用种子类用测试数据为数据库设定种子的简单方法。

当我阅读此描述时,这些解决方案似乎都没有被改编。

在stackoverflow上也提出了类似的问题并得到了回答。答案建议使用数据库播种器通过检测当前环境来填充数据库:

<?php

class DatabaseSeeder extends Seeder {

    public function run()
    {
            Eloquent::unguard();

            if (App::environment() === 'production')
            {
                $this->call('ProductionSeeder');
            }
            else
            {
                $this->call('StagingSeeder');
            }
    }

}

当然,此解决方案有效。但我不确定这是正确的方法,因为通过使用播种器插入数据,您将失去迁移机制提供的所有优势(数据库升级,回滚...

我想知道在这种情况下的最佳实践是什么。


答案 1

Laravel的发展是关于自由的。因此,如果您需要为生产数据库设定种子,并认为 DatabaseSeeder 是这样做的最佳位置,为什么不呢?

好吧,播种机主要用于测试数据,但你会看到有些人像你一样使用它。

我认为这种重要的种子是我的迁移的一部分,因为这是我的数据库表中无法实现的东西,并且每次我部署新版本的应用程序时都会运行,所以我只是这样做artisan migrate

php artisan migrate:make seed_models_table

并在其中创建我的 seedind 内容:

public function up()
{
    $models = array(
        array('name' => '...'),
    );

    DB::table('models')->insert($models);
}

答案 2

我经常发现自己想知道这个问题的正确答案是什么。就个人而言,我会避免使用种子设定来填充数据库中所需的行,因为您必须放入大量条件逻辑,以确保您不会尝试填充已经存在的内容。(删除和重新创建数据是非常不明智的,因为您可能最终出现键不匹配,如果您使用的是级联删除,则可能会意外地错误地擦除数据库的负载! ;-)

我将行的“种子设定”放入迁移脚本中,因为作为推出过程的一部分,数据需要存在。

值得注意的是,您应该使用DB类而不是Eloquent模型来填充此数据,因为您的类结构可能会随着时间的推移而变化,这将阻止您从头开始重新创建数据库(无需重写历史记录和更改迁移文件,我确信这是一件坏事。

我倾向于使用这样的东西:

public function up()
{
    DB::beginTransaction();

    Schema::create(
        'town',
        function (Blueprint $table) {
            $table->increments('id');
            $table->string('name');
            $table->timestamps();
        }
    );

    DB::table('town')
        ->insert(
            array(
                array('London'),
                array('Paris'),
                array('New York')
            )
        );

    Schema::create(
        'location',
        function (Blueprint $table) {
            $table->increments('id');
            $table->integer('town_id')->unsigned()->index();
            $table->float('lat');
            $table->float('long');
            $table->timestamps();

            $table->foreign('town_id')->references('id')->on('town')->onDelete('cascade');
        }
    );
    
    DB::commit();
}

这样,当我第一次创建城镇表时,它就可以很容易地“播种”它,并且不会干扰在运行时对它所做的任何添加。


推荐