2011-10-07 27 views
65

你必須承認,對於rails和數據庫的新手來說,關於rubyonrails.org的官方解釋使得所有這四項任務完全一樣。 Quote:db:test:clone,db:test:clone_structure,db:test:load,db:test:prepare?有什麼區別?

rake db:test:clone Recreate the test database from 
        the current environment’s database schema 

rake db:test:clone_structure Recreate the test database from the 
           development structure 

rake db:test:load Recreate the test database from the current schema.rb 

rake db:test:prepare Check for pending migrations and load the test schema 

我甚至不知道結構和模式之間的區別。加載當前環境的模式和加載schema.rb有什麼區別?

這些任務有多相似(或不同)?

回答

61

非常好的問題。難道我難倒了,所以我進入了鐵軌源並拉起database.rake。現在,它更清楚:

db:test:clone只是一個db:schema:dumpdb:test:load組合:

task :clone => %w(db:schema:dump db:test:load) 

db:test:clone_structure使用{} RAILS_ENV文件_structure.sql:

task :clone_structure => [ 'db:structure:dump', 'db:test:purge' ] do 
    # skipped some code, here's what happens for MySQL: 
    ActiveRecord::Base.establish_connection(:test) 
    # ... 
    IO.readlines("#{Rails.root}/db/#{Rails.env}_structure.sql").join.split("\n\n").each do |table| 
    ActiveRecord::Base.connection.execute(table) 
    end 
end 

db:test:load相同db:schema:load ,但在測試數據庫上調用它:

task :load => 'db:test:purge' do 
    ActiveRecord::Base.establish_connection(ActiveRecord::Base.configurations['test']) 
    # ... 
    db_namespace['schema:load'].invoke 
end 

db:test:prepare通知您是否有任何遷移掛起,如果沒有,則運行db:test:clone_structure(使用{rails_env} _structure.sql文件)或db:test:load(使用schema.rb文件),具體取決於模式格式(這是有點讓我困惑,也許其他人可以擴展它):

task :prepare => 'db:abort_if_pending_migrations' do 
    # ... 
    db_namespace[{ :sql => 'test:clone_structure', :ruby => 'test:load' }[ActiveRecord::Base.schema_format]].invoke 
end 

希望這個清除它!再次,通過database.rake文件很容易,並會清除您可能有的任何其他問題。該鏈接轉到test命名空間開始的那一行。

+0

底線:他們幾乎都是一樣的東西。 :-p – bricker

+0

警告 - 我發現db:test:clone沒有正確地從我的開發數據庫複製列的可空性。這可能是一個隨後被修復的舊bug,因爲我發現它使用Rails 2.3.12。 –

20

他們其實不是一回事。任何包含單詞「schema」的任務都會作用於.../db/schema.rb文件。在應用所有遷移之後,schema.rb實際上是您的模式的狀態。它可以被執行來恢復你的模式,而不是運行所有數據庫遷移(如果你有很多遷移可能需要很長時間)。

任何帶有「結構」一詞的任務都會對{Rails.env} _structure.sql文件起作用。當您的模式包含無法在schema.rb文件中表達的結構時使用此文件。例如,如果您使用特定於特定RDBMS的功能。在封面下,rails使用適合您的RDBMS的任何模式轉儲實用程序生成此文件。爲了恢復模式,它使用特定於RDBMS的工具讀入文件並重新執行SQL語句。

的Rails知道是否要基於該schema.rb路線或structure.sql路線,你是否已經設置

config.active_record.schema_format =:SQL

在你的... /config/application.rb

+1

上面磚匠的回答很好的擴展 - 謝謝! –

+0

事情的例子可能不同:觸發器,函數和存儲過程。 (這就是爲什麼我們仍然堅持使用結構)。 –