2012-07-04 5 views
0

모델이 Clients이고 lastnamefirstname 열을 가진 해당 데이터베이스가 있습니다. 원래는 [lastname, firstname]의 고유성에 대한 제약이 없었으며 현재 데이터베이스에 중복 된 내용이 포함되어 있습니다. 데이터베이스를 정리하고 모델에 제약 조건을 적용하고 싶습니다 (예 : validates_uniqueness_of :lastname, scope: :firstname).채워진 데이터베이스에 제약 조건 적용 (제약 조건을 위반하는 레코드 포함)

아이디어는 어떤 방식 으로든 데이터를 백업하고 빈 모델 데이터베이스에 제약 조건을 적용한 다음 데이터를 중복으로 가져 와서 별도로 처리하여 예외로부터 복구 할 수있게하는 것입니다.

그러나 나는 여기서 뭔가를하고 있다고 느낍니다.

더 나은 "레일 방식"이 있습니까?

답변

1

문제를 발견 할 수있는 유일한 순수한 방법은 모든 모델을 실행하고 그것이 여전히 유효한지 확인하는 것입니다. 예를 들어, 약 : 너무 많은 메모리를 필요로하는 경우

Client.all.each do |client| 
    unless (client.valid?) 
    puts "Client #{client.id} invalid: #{client.errors.full_messages}" 
    end 
end 

로드 all 기록은 좋은 생각이 될 수 있습니다. ActiveRecord 3.0은 이것에 대해 더 똑똑 해지고, 청크로로드되지만, 현재로서는 그 사실을 증명할 수 없습니다. 당신은 중복 된 데이터를 무엇에 관해서는

:

  • 항상 백업하여 테이블 적절한 데이터베이스 스냅 숏 도구를 사용하여 시작하기 전에.
  • 항상 프로덕션 데이터베이스에서 실행하기 전에 데이터 사본에서 수정 사항을 테스트하십시오.
  • 항상 신뢰할 수 있고 예측 가능한 방식으로 작업을 수행하는 레일스 마이그레이션을 작성하여 변경 사항을 기록하십시오. 배포하기 전에 반복적으로 테스트하십시오.

프로덕션 데이터베이스가 그대로 정상적인 스냅 샷의 영향을 받았다고 가정하면 테스트 데이터를 가져올 수 있습니다. 그렇지 않은 경우 우선 순위를 확인해야합니다.

+0

나는 여전히 잘못된 레코드를 정리하는 방법을 궁금해합니다. 클라이언트가 유효하지 않아'client.destroy'는 작동하지 않습니다. 이것을 해결하기 위해 여분의 필드 'dupe'를 추가하고 고유성 검증을 'validates_uniqueness_of : lastname, scope : [: firstname, : dupe]'로 변경했습니다. 'client.dupe = true; client.destroy'는 (자연스럽게) 작업했습니다. –

+1

일괄 처리를 반복하려면 Client.find_each를 사용하십시오. –