我想在我的Rails應用程序中對數據庫(在我的情況下爲POSTGRES)進行批量插入數千條記錄。批量插入導軌3
這樣做的「Rails方式」是什麼? 一些快速且正確的做法。
我知道我可以通過字符串連接的屬性創建SQL查詢,但我想要一個更好的方法。
我想在我的Rails應用程序中對數據庫(在我的情況下爲POSTGRES)進行批量插入數千條記錄。批量插入導軌3
這樣做的「Rails方式」是什麼? 一些快速且正確的做法。
我知道我可以通過字符串連接的屬性創建SQL查詢,但我想要一個更好的方法。
ActiveRecord .create
方法支持批量創建。如果數據庫不支持該方法,並且在支持該功能的情況下使用底層數據庫引擎,則該方法會模擬該功能。
只需傳遞一組選項。
# Create an Array of new objects
User.create([{ :first_name => 'Jamie' }, { :first_name => 'Jeremy' }])
支持塊,這是共享屬性的常用方法。
# Creating an Array of new objects using a block, where the block is executed for each object:
User.create([{ :first_name => 'Jamie' }, { :first_name => 'Jeremy' }]) do |u|
u.is_admin = false
end
所以你認爲對於postgres的情況它會創建一個單一的插入語句? – phoenixwizard
它可能取決於驅動程序版本和PG版本。您可以在您的控制檯中嘗試它並查看執行的SQL語句。 –
它似乎在創建單獨的查詢。儘管通過交易包圍它似乎在加快速度。任何方式,我可以確保單個查詢插入? – phoenixwizard
您可以創建在你的軌道模型中的腳本,編寫查詢該腳本 插入在軌可以運行使用
rails runner MyModelName.my_method_name
的是,我在我的項目中使用的最佳方法腳本。
更新:
我使用後在我的項目,但它是不恰當的SQL注入攻擊。 如果您未在此查詢中使用用戶的輸入,可能你
user_string = " ('[email protected]','a'), ('[email protected]','b')"
User.connection.insert("INSERT INTO users (email, name) VALUES"+user_string)
多個記錄的工作:
new_records = [
{:column => 'value', :column2 => 'value'},
{:column => 'value', :column2 => 'value'}
]
MyModel.create(new_records)
我正在尋找像在單個查詢中插入1000個對象到數據庫中的東西。 用例:我從Facebook登錄用戶,並通過一次數據庫調用保存所有Facebook朋友。 – phoenixwizard
嗨,@Aram Bhusal,請看我最新的答案。 –
這正是我想避免:)看來它要麼這樣或更慢的方式... – phoenixwizard
你能做到快速路或Rails的方式;)的根據我的經驗,將大量數據導入到Postgres的最佳方式是通過CSV。使用Postgres的本地CSV導入功能需要幾分鐘的時間Rails方式需要幾秒鐘的時間。
http://www.postgresql.org/docs/9.2/static/sql-copy.html
它甚至觸發數據庫觸發器和尊重數據庫的約束。
編輯(在您的評論之後): Gotcha。在那種情況下,你已經正確地描述了你的兩個選擇我之前一直處於同樣的狀況,使用Rails 1000保存實現它!策略,因爲這是最簡單的工作,然後將其優化爲「追加龐大的查詢字符串」策略,因爲它的表現更好。
當然,不成熟的優化是所有邪惡的根源,所以也許可以使用簡單的慢速Rails方法,並且知道構建一個大的查詢字符串是一個完美合法的技術,以犧牲維護性爲代價進行優化。我覺得你真正的問題是'是否有Railsy的方式,不涉及1000年的查詢?' - 不幸的是,答案是否定的。
我覺得我的問題不清楚。 我正在考慮用戶使用他的Facebook帳戶登錄的用例,我正在保存他的所有朋友。我一次預計大約有1000到4000條記錄。我想從我的Rails應用程序中做到這一點 – phoenixwizard
@Simone Carletti和@Sumit Munot的兩個答案後,我終於達成了一個解決方案。
直到Postgres的驅動程序支持的ActiveRecord .create方法的批量插入,我想一起去activerecord-import gem。它在一個插入語句中進行批量插入。
books = []
10.times do |i|
books << Book.new(:name => "book #{i}")
end
Book.import books
在POSTGRES這導致單個插入statemnt。
一旦Postgres的驅動程序支持在單個插入語句ActiveRecord的.create方法的批量插入,然後@Simone Carletti酒店的解決方案更有意義:)
參見:如何實現在Rails的批量插入3] (http://stackoverflow.com/questions/8505263/how-to-implement-bulk-insert-in-rails-3)和[批量插入記錄到活動記錄表(http://stackoverflow.com/questions/ 15317837 /大容量插入 - 記錄 - 進入 - 活性 - 記錄表)。 – 2014-04-13 05:06:17