2013-03-13 2 views
1

원본 테이블에 제약 조건이없는 중복 키 레코드가있을 때까지 한 테이블에서 다른 테이블로 데이터를로드하기 위해 매일 루비 스크립트 작업을 실행했습니다. 내 대상 테이블은 대상 테이블에 열 (head_date, center_id, site_url)에 대한 기본 키 제약 조건이있는 해당 레코드를 거부했습니다. 프로그램이 멈추었고 명령 줄에서 아래 오류를 보여주었습니다.Ruby에서 ActiveRecord :: RecordNotUnique 예외를 catch하고 무시하는 방법

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은 오류를 catch 할 것으로 예상됩니다. 버블을 일으키지 않으면 그 오류를 삼킬 것입니다. 코드는 예외없이 계속 실행됩니다.

+0

예외가 self.table_name = 'master.target_tbl'을 둘러싸도록해야합니까? 왜 그런가요? 나는 그것이 실제로 삽입하는 부분이나 siteData.save 명령을 둘러싸 야한다고 생각했다. 내가 더 잘 이해할 수 있도록 논리를 알려주십시오 .. 고마워. – Doublespeed

+0

예, '저장'할 때 발생합니다. Fixed – AdamT

-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

BTW - 여전히 오류가있는 경우 사용자'begin ... rescue => e ... end' 블록을 사용할 수 있습니다. 하지만 여기에 오류가 있어서는 안됩니다;) – NilColor

+0

흠 ... 왜 아래로 투표? 의견을 남겨주세요. – NilColor

관련 문제