2014-02-05 177 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