2011-10-18 82 views
7

我有一個Rails 3應用程序,我需要將外部系統提供的XML文件提取到Postgres數據庫中。我想使用類似ActiveRecord-Import的東西,但是這似乎不能處理Postgres的upsert功能,並且我將要攝取的一些記錄已經存在,但需要更新。Bulk onsert with Ruby on Rails

我正在閱讀的大部分內容都建議儘快編寫SQL,但這似乎是一個可能已經解決的問題。我無法找到它。

謝謝。

+0

我不確定Rails是否正確。您是否考慮過使用現有的XML和PostgreSQL工具在Rails之外進行此操作? –

+0

一旦進入數據庫,插入的數據就成爲用於其他目的的模型,可以通過網絡進行編輯等等,我們對模型進行驗證和關聯。我擔心打破軌道會導致我們複製大量的工作,並使維護變得困難。 –

+3

如果您希望ActiveRecord驗證運行,您將不得不一次插入一條記錄。如果你想批量更新+驗證,那麼你將不得不在數據庫端設置驗證/約束。如果你想在這種情況下效率,你可能不得不妥協代碼可維護性 –

回答

-1

它是一個兩步走的事情。首先,您需要獲取XML文件。如果它由用戶通過一種形式提供給你的運氣,否則你需要使用標準的HTTP庫來獲取它,或者像機械化的一些寶石(實際上真的很棒)。

第二件事很簡單。你讀所有的XML轉換成字符串,然後你可以將其轉換成一個哈希這個PICE代碼:

Hash.from_xml(xml_string) 

然後你可以分析和處理數據的工作...

+0

我們正在使用happymapper來解析XML,並且工作得很好。造成這種困難的因素是,如果我們逐一插入/更新每個對象,我們想要攝取的對象數量會非常緩慢。 –

7

你可以做upserting在MySQL和PostgreSQL上使用upsert

如果你正在尋找原始速度,你可以使用nokogiri和upsert。

使用data_miner導入數據可能更容易,該數據在內部使用nokogiri和upsert。

+0

我希望我早點看到了這個答案 – sheerun

1

如果您使用的是PostgreSQL 9.1,則應使用可寫的公用表表達式。喜歡的東西:

WITH updates (id) AS (
    UPDATE mytable SET ..... 
     WHERE .... 
    RETURNING id 
) 
INSERT INTO mytable (....) 
SELECT ... 
    FROM mytemptable 
WHERE id NOT IN (select id from updates); 

在這種情況下,你批量過程中臨時表變薄第一,那麼它會嘗試按照你的邏輯從不是Temptable更新記錄,並插入休息。