2014-02-05 98 views
29

我的应用程序需要预先注册的数据集才能工作。所以我需要在设置应用程序时将它们插入到数据库中。Laravel:迁移和播种生产数据

Laravel提出了两种机制:

  • Database migrations“他们让一个团队来修改数据库模式,并保持最新的当前模式的状态。”
  • Database seeding“Laravel还提供了一种简单的方法,使用种子类为测试数据创建数据库。”

当我阅读本说明时,这些解决方案似乎都没有适应。

一个类似的问题是asked on stackoverflowanswered。答案提出通过检测当前环境中使用的数据库播种机来填充数据库:

<?php 

class DatabaseSeeder extends Seeder { 

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

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

} 

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

我想知道在这种情况下是最佳做法。

+0

在Laravel中,迁移是关于模式管理,而不是数据管理。播种机被用来提供测试数据,但我认为他们的意图不是生产数据加载机制。 – warspite

+2

@尽管是这是文档说的。这就是为什么我问这个问题。 – gontard

+2

也许这个软件包会有帮助https://github.com/slampenny/SmartSeeder –

回答

46

Laravel的发展是关于自由。因此,如果您需要为您的生产数据库播种并认为DatabaseSeeder是最好的选择,为什么不呢?

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

我看到这重要的一类种子作为我的迁移的一部分,因为这一点是无法走出我的数据库表和artisan migrate是跑了,每次我部署我的应用程序的新版本,所以我只是做

php artisan migrate:make seed_models_table 

,并在其中创建我seedind的东西:

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

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

感谢您的回答安东尼奥。我将使用迁移种子。 – gontard

+0

这是一个很好的答案。迁移管理模式,但有时候需要移动数据。这一切都需要以严格的顺序完成,并且迁移能够执行这个顺序。 – Jason

22

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

我把'如果有机会,将行播种到迁移脚本中,数据将作为部署过程的一部分。

值得注意的是,您应该使用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(); 
} 

这就让我“种子”的城镇表很容易,当我第一次创建它,并与它所做的任何增加不会干涉在运行时。

+0

谢谢你丹的贡献。我现在使用迁移,我认为它也是种子数据的正确地方。 – gontard

+2

有趣的点使用数据库而不是模型 – alariva

+1

我知道这已经超过一年了,但上述实际上是否工作?我想你会得到一个“非空违规”,因为在插入表时,你不包括“created_at”和“updated_at”字段。 – Thelonias