我有一個超過一千個鍵/值對的哈希。從一個哈希更新許多行而不只是循環在Rails中
我有一個數千行的數據庫表。
因此,蠻力的基於散列表的更新非常簡單。例如:
my_hash.each{|key,value|
Model.update_all("column2 = #{value}", "column1 = #{key}")
}
但是,這會做超過一千個SQL更新語句。
有沒有什麼好的方法(在Rails中)使用一個(或幾個)更新語句來完成此操作?
我有一個超過一千個鍵/值對的哈希。從一個哈希更新許多行而不只是循環在Rails中
我有一個數千行的數據庫表。
因此,蠻力的基於散列表的更新非常簡單。例如:
my_hash.each{|key,value|
Model.update_all("column2 = #{value}", "column1 = #{key}")
}
但是,這會做超過一千個SQL更新語句。
有沒有什麼好的方法(在Rails中)使用一個(或幾個)更新語句來完成此操作?
好吧,我已經用Mike Woodhouse和ttarchala的提示解決了這個問題。下面的代碼(我用的是Ruby Sequel gem)
# connect to the database
DB = Sequel.connect("postgres://user:[email protected]/blah")
# create the temporary table
DB.create_table :temp_update, :temp => true do
primary_key :key
String :value
end
# insert rows from the hash (multi_insert takes an array of hashes,hence the map)
DB[:temp_update].multi_insert(my_hash.map{|k,v| {:key => k, :value => v}})
# Do the update based on a join
DB.execute(" UPDATE my_table
SET column2 = temp_update.value
FROM temp_update
WHERE column1 = temp_update.id")
我使用Postgres的,所以確切的更新SQL可能是其他RDBMS不同。
是的。我不知道具體是對鐵軌,但你可以使用SQL關鍵字,它的工作原理是:
select * from table where column in ('list', 'of', 'values')
最快的方法 - 在任何語言,不知道它是如何在Rails中做專門 - 將把你的內存散列轉儲到數據庫中的一個臨時表中,該數據庫只有你的散列鍵和值的列,然後發出一個UPDATE命令,並加入一個連接你的表的新的臨時表。
檢查查詢計劃以確保優化器按原樣工作,在發佈更新之前在臨時表上構建一個臨時索引。如果不是,請自行構建索引。
+1,但是,這隻會工作如果你可以加載你的哈希表比你更快地運行更新 – cjk
謝謝。我知道這種方法,但不知道如何在Rails中:( – DanSingerman
我不確定「好」,但在許多DBMS平臺上,可以在一次執行中發送多個SQL語句。例如,ar-extensions gem可以幫助批量INSERT語句,儘管取決於平臺可能需要稍微調整 - 例如,Oracle有點棘手。我不認爲它直接處理UPDATE,但你可以從這裏的另一個答案使用臨時表技巧:批量加載數據並使用ActiveRecord.execute
運行UPDATE。在某種意義上說,它可能是可能的,但話又說回來,滑軌(或者更準確的ActiveRecord)從未打算將ORM功能用於絕對一切
可能只有「好」的,這就是爲什麼存在之類的東西find_by_sql
:他們當你知道一個更好的方法時,在那裏度過。
我已經使用了ar-extensions,它效果很好。 – semanticart
這不是一個更新 – DanSingerman
我會幫他:更新表SET字段=值,field2 = value2 WHERE id在(3,8,33,756,6543,54637) – chrishomer