[英]Rails: does minitest use schema.rb to recreate the test schema?
我試圖讓傳統的Rails系統達到更新的標准,但是在測試數據庫反映schema.rb
的狀態以及通過遷移進行的更改方面遇到了問題。
tl; dr運行rake minitest:all
調用與rake db:schema:load
相同的代碼?
該系統最初是由非軟件工程師,不知道Rails等人員建立的。添加了幾種特定於MySQL的類型(例如unsigned int
),這些類型沒有使用Rails的遷移和schema.rb
特別支持。 所以系統使用了structure.sql
並且對於如何保持更新,檢入git等等非常草率。
此外,在某些時候,有人決定用包含自生成GUID的varchar
替換一些通常的數字,自動遞增主鍵id
字段。 字段名稱仍然是id
但它是一種新的數據類型。
但是所有的數百個測試(他們確實寫了很多測試)已經寫入基於id的參考夾具實例,而不是夾具名稱,夾具之間存在依賴關系等。他們決定堅持使用,而不是更新測試。用於測試的舊模式(帶有數字id
),並使用新模式(在id
使用varchar GUID)進行生產。
OP深呼吸......
各種環境的數據庫不同步,有數百次遷移,但由於共享了“開發”數據庫,它們停止了工作......你知道,這是一團糟。
我試圖修復所有這些,並最終轉移到PostgreSQL。
我使用RAILS_ENV=production rake db:structure:dump
在本地從生產數據庫中轉儲了模式 - 這產生了一個權威的structure.sql
。 我創建了一個新的開發數據庫,並使用rake db:structure:load
加載了它的模式 - 我仔細比較了生產和開發模式,它們是相同的,甚至是我上面提到的特定於MySQL的unsigned int。
我想轉向使用schema.rb
有兩個原因。 首先,我想進入一個不依賴於MySQL的系統。 其次,當使用structure.sql
我們檢查一個文件,該文件具有自動增量值,數據庫設置以及運行最新db:migrate
的任何機器的其他特性。 這可能會產生我寧願避免的問題。
因此,我在本地更改了配置設置:sql
以使用:ruby
設置生成schema.rb
。
但schema.rb
真的不喜歡將id
字段轉換為varchar
的想法 - 我確保所有使用它的模型聲明self.primary_key = :id
,然后我創建了一個新的遷移來替換所有舊的,“匯總遷移”,其內容主要是新的schema.rb
,但在幾個方面進行了修改。
特別是,如果id
字段是GUID varchar
我就像這樣設置表(從遷移中):
class RolledUpStateAsOf20150403 < ActiveRecord::Migration
def up
# ... all other table definitions in the system
create_table "users", :id => false, :force => false do |t|
t.string "id", :limit => 36, :default => "", :null => false
t.string "login"
# and all the other user fields
end
execute("ALTER TABLE users ADD PRIMARY KEY (id);")
#...
end
def down
raise ActiveRecord::IrreversibleMigration
end
end
所以:
:id => false
以防止遷移創建正常ID :force => false
以確保此遷移不會破壞生產數據庫 t.string "id"
具有大小和其他類似主鍵的設置 execute(ALTER TABLE ...)
以將id聲明為主鍵 每次我在將來創建一個新的遷移時, schema.rb
都會更新 - 它現在不准確(直到我們以后擺脫那些古怪的id
字段)。 遷移將尊重正常的Rails實踐。
一旦生產,登台,開發和其他數據庫同步,那么一切都很順利。
除了我們測試。
我正在使用minitest運行測試,如下所示:
RAILS_ENV=test rake db:drop
RAILS_ENV=test rake db:create
RAILS_ENV=test rake db:migrate
RAILS_ENV=test rake minitest:all
但后來我開始看到錯誤,錯誤是由於id
列被定義為int
而不是varchar
。
如果我在運行minitest之前檢查架構(在drop
, create
和my magic migration之后),那就是正確的:根據需要,時髦的主鍵是varchar
。
但是在測試期間的某個地方看起來模式正在變回Rails標准。 我可以返回並檢查ID列返回int
。
據推測,模式是從實際的schema.rb
。
這是正常/預期的行為嗎? 關於如何實現我的目標的任何建議,簡單地說:
varchar
基於GUID的id
字段 structure.sql
如果可能的話 好吧,我相信下面的是真實的:MINITEST,或測試不運行db:schema:load
...或db:structure:load
運行時RAILS_ENV=test
-這可以通過運行既可以觀察到rake test --trace
或rake minitest:all --trace
。
所以,因為我的schema.rb
不會完全重新創建數據庫,因為varchar
而不是int
用於名為id
的字段...我不得不恢復使用structure.sql
。
解決方案的其余部分,包括添加手動修改版本的schema.rb
作為第一個“匯總”遷移工作很好,后續遷移很好。 未來的某個時候,我會把ids變回自然形態; 目前,這是一個合適的解決方案,如果不是優雅的話。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.