2013-03-13 113 views
1

我每天運行ruby腳本作業來將數據從一個表加載到另一個表,直到源表中找到重複的鍵記錄爲止,因爲該表沒有約束。我的目標表拒絕了這些記錄,因爲目標表對列具有主鍵約束(head_date,center_id,site_url)。我的程序剛剛停止,並在命令行中顯示下面的錯誤。 :-(如何捕捉和忽略Ruby中的ActiveRecord :: RecordNotUnique異常

in `async_exec': PG::Error: ERROR: duplicate key value violates unique constraint "tst_data_pkey" (ActiveRecord::RecordNotUnique) 

我可以期待源表有其他討厭的記錄是這樣的。我該如何繼續處理,並抓住這個活動記錄異常後移動到下一個記錄?

下面是我更新/插入代碼:

class SiteSection < ActiveRecord::Base 

    SiteSection.establish_connection(
     :adapter => 'postgresql', 
     :host  => 'hoster-of-hosts.com', 
     :database => 'super-inven', 
     :username => 'user', 
     :password => 'pass' 
        ) 
    self.table_name = 'master.target_tbl' # << insert into this table 
end 

conn.query("select * from source_tbl") do |row| 
    siteData = SiteSection.find_or_initialize_by_head_date_and_center_id_and_site_url(row[:date_c], row[:com_id], row[:site_link]) 

    siteData[:head_date]  = row[:date_c] 
    siteData[:center_id]  = row[:com_id] 
    siteData[:site_url]   = row[:site_link].nil? ? 'unknown' : row[:site_link] 
    siteData[:people_cnt]  = row[:persons].nil? ? 0 : row[:persons] 
    siteData[:ips]  = row[:ip_adds].nil? ? 0 : row[:ip_adds] 

    siteData.save 
i = i+1 
puts "finished: #{i}" if i % 10000 == 0 
end 
conn.close 

回答

3

您可以使用

begin 

rescue => e 

end 

像這個:

class SiteSection < ActiveRecord::Base 

    SiteSection.establish_connection(
     :adapter => 'postgresql', 
     :host  => 'hoster-of-hosts.com', 
     :database => 'super-inven', 
     :username => 'user', 
     :password => 'pass' 
        ) 
    self.table_name = 'master.target_tbl' # << insert into this table 
end 

conn.query("select * from source_tbl") do |row| 
    siteData = SiteSection.find_or_initialize_by_head_date_and_center_id_and_site_url(row[:date_c], row[:com_id], row[:site_link]) 

    siteData[:head_date]  = row[:date_c] 
    siteData[:center_id]  = row[:com_id] 
    siteData[:site_url]   = row[:site_link].nil? ? 'unknown' : row[:site_link] 
    siteData[:people_cnt]  = row[:persons].nil? ? 0 : row[:persons] 
    siteData[:ips]  = row[:ip_adds].nil? ? 0 : row[:ip_adds] 

    begin 
    siteData.save 
    rescue => e 
    puts e.message 
    puts "Error happened but I'll just keep chuggin along" 
    end 
i = i+1 
puts "finished: #{i}" if i % 10000 == 0 
end 
conn.close 

rescue => e預計會發生錯誤。它會通過不讓它冒泡來吞噬這個錯誤。您的代碼將繼續運行,而不會異常崩潰。

+0

你確定它需要包含self.table_name ='master.target_tbl'嗎?這是爲什麼?我認爲它應該圍繞它實際插入的部分或siteData.save命令。請讓我知道邏輯,以便我能更好地理解..謝謝。 – Doublespeed 2013-03-13 04:07:35

+0

是的,它會在'save'上得到提升。固定 – AdamT 2013-03-13 04:28:55

-1

如果你有獨特的鑰匙,你應該使用它 - 是這樣的:

i = 0 
puts 'loading records' 
conn.query("select * from source_tbl") do |row| 
    rec = SiteSection.where(
    :head_date => row[:date_c], 
    :center_id => row[:com_id], 
    :site_url => (row[:site_link] || 'unknown') 
).first_or_initialize 

    rec.people_cnt = (row[:persons] || 0) 
    rec.ips => (row[:ip_adds] || 0) 

    rec.save! 

    i += 1 
    print '.' if i % 10000 == 0 
end 
puts "done\ntotal records: #{i}" 

這樣,您將節省(新)的記錄或更新的人(如果找到)。沒有ActiveRecord::RecordNotUnique應該在這裏,如果你沒有改變你的pkey!

+0

順便說一句 - 如果你仍然有一個錯誤,你可以用戶'開始...救援=> e ...結束「塊。但你不應該在這裏有一個錯誤;) – NilColor 2013-03-18 21:17:58

+0

嗯......爲什麼倒票?請留下評論。 – NilColor 2013-07-25 11:53:40