복붙노트

[RUBY-ON-RAILS] 어떻게 sqlite3를 "기본 값 NULL과 NOT NULL 열을 추가 할 수 없습니다"해결하기 위해?

RUBY-ON-RAILS

어떻게 sqlite3를 "기본 값 NULL과 NOT NULL 열을 추가 할 수 없습니다"해결하기 위해?

기존 테이블에 NOT NULL 열을 추가하는 동안 나는 다음과 같은 오류를 얻고있다. 왜이 일어나고있다?. 기존 레코드가 문제가 있음을 다시 생각을하지만, 심지어 DB, 문제의이 지속 재설정 후 : 나는 갈퀴 DB를 시도했다. 도움을 기쁘게 할 날이 밖으로 그림.

마이그레이션 파일

class AddDivisionIdToProfile < ActiveRecord::Migration
  def self.up
    add_column :profiles, :division_id, :integer, :null => false
  end

  def self.down
    remove_column :profiles, :division_id
  end
end

에러 메시지

해결법

  1. ==============================

    1.이미 테이블의 행을 가지고, 당신은 새로운 열 division_id를 추가하고 있습니다. 그것은 기존의 각 행에서 그 새 열 뭔가를 필요로한다.

    이미 테이블의 행을 가지고, 당신은 새로운 열 division_id를 추가하고 있습니다. 그것은 기존의 각 행에서 그 새 열 뭔가를 필요로한다.

    SQLite는 일반적으로 NULL을 선택할 것,하지만 당신은이 NULL이 될 수 없습니다 지정한, 그래서 무엇을해야 하는가? 그것은 알 수있는 방법이 있습니다.

    보다:

    그 블로그의 추천은 NOT NULL 제약없이 열을 추가하는 것입니다, 그것은 모든 행에 NULL로 추가됩니다. 그럼 당신은 NOT NULL 제약 조건을 추가 할 수 change_column를 사용하여 다음 division_id의 값을 입력 할 수 있습니다.

    나는이 세 단계 과정을 수행하는 마이그레이션 스크립트의 설명에 링크 된 블로그를 참조하십시오.

  2. ==============================

    2.이 SQLite는과 함께 글리치 (나는 고려할 것)입니다. 이 오류는 모든 레코드 테이블의 여부가 있는지 여부를 발생합니다.

    이 SQLite는과 함께 글리치 (나는 고려할 것)입니다. 이 오류는 모든 레코드 테이블의 여부가 있는지 여부를 발생합니다.

    "널 (null) => false"로 표기 처음부터 테이블을 추가 할 때, 당신은 당신이와 무슨 일을하는지 인 NOT NULL을 지정할 수 있습니다. 열을 추가 할 때, 당신은이 작업을 수행 할 수 없습니다. SQLite는의 사양은 가난한 선택이에 대한 기본을 가져야했다. 즉, 데이터 무결성 - 그것은 NOT NULL 외래 키를 갖는 목적을 패배 때문에 기본 값을 추가하는 옵션을 선택하지 않습니다.

    다음은이 결함을 주위에 얻을 수있는 방법, 그리고 당신은 모두 같은 마이그레이션을 할 수 있습니다. 참고 :이 이미 데이터베이스에 기록이없는 경우입니다.

    class AddDivisionIdToProfile < ActiveRecord::Migration
      def self.up
        add_column :profiles, :division_id, :integer
        change_column :profiles, :division_id, :integer, :null => false
      end
    
      def self.down
        remove_column :profiles, :division_id
      end
    end
    

    우리는 즉시 제약 조건을 추가하려면 열을 변경의 NULL 제약 조건없이 열을 추가하고 있습니다. SQLite는 외관상으로 매우 열 추가시 우려되는 동안, 너무 열 변화에 까다 롭고하지 있기 때문에 우리는이 작업을 수행 할 수 있습니다. 이것은 나의 책에 명확한 디자인 냄새입니다.

    그것은 확실히 해킹,하지만 여러 마이그레이션보다 짧은 그리고 그것은 여전히 ​​프로덕션 환경에서보다 강력한 SQL 데이터베이스와 함께 작동합니다.

  3. ==============================

    3.기존 행이있는 테이블이 경우에 당신은 당신의 널 제약 조건을 추가하기 전에 기존 행을 업데이트해야합니다. 마이그레이션에 대한 가이드과 같이, 로컬 모델을 사용하는 것이 좋습니다 :

    기존 행이있는 테이블이 경우에 당신은 당신의 널 제약 조건을 추가하기 전에 기존 행을 업데이트해야합니다. 마이그레이션에 대한 가이드과 같이, 로컬 모델을 사용하는 것이 좋습니다 :

    4까지 레일 :

    class AddDivisionIdToProfile < ActiveRecord::Migration
      class Profile < ActiveRecord::Base
      end
    
      def change
        add_column :profiles, :division_id, :integer
    
        Profile.reset_column_information
        reversible do |dir|
          dir.up { Profile.update_all division_id: Division.first.id }
        end
    
        change_column :profiles, :division_id, :integer, :null => false
      end
    
    end
    

    3 레일

    class AddDivisionIdToProfile < ActiveRecord::Migration
      class Profile < ActiveRecord::Base
      end
    
      def change
        add_column :profiles, :division_id, :integer
    
        Profile.reset_column_information
        Profile.all.each do |profile|
          profile.update_attributes!(:division_id => Division.first.id)
        end
    
        change_column :profiles, :division_id, :integer, :null => false
      end
    
    end
    
  4. from https://stackoverflow.com/questions/3170634/how-to-solve-cannot-add-a-not-null-column-with-default-value-null-in-sqlite3 by cc-by-sa and MIT license