Nice programing

SQLite3에서 "기본 값이 NULL 인 NOT NULL 열을 추가 할 수 없음"을 해결하는 방법은 무엇입니까?

nicepro 2020. 12. 31. 23:28
반응형

SQLite3에서 "기본 값이 NULL 인 NOT NULL 열을 추가 할 수 없음"을 해결하는 방법은 무엇입니까?


기존 테이블에 NOT NULL 열을 추가하는 동안 다음 오류가 발생합니다. 왜 일어나고 있습니까?. rake db : reset은 기존 레코드가 문제라고 생각했지만 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

에러 메시지

SQLite3 :: SQLException : 기본값이 NULL 인 NOT NULL 열을 추가 할 수 없습니다. ALTER TABLE "profiles"ADD "division_id"integer NOT NULL


표에 이미 행이 있고 새 열을 추가하고 있습니다 division_id. 각 기존 행의 새 열에 무언가가 필요합니다.

SQLite는 일반적으로 NULL을 선택하지만 NULL이 될 수 없다고 지정 했으므로 무엇이어야합니까? 알 방법이 없습니다.

보다:

해당 블로그의 권장 사항은 not null 제약 조건없이 열을 추가하는 것이며 모든 행에 NULL로 추가됩니다. 그런 다음에 값을 입력 한 division_id다음를 사용 change_column하여 null이 아닌 제약 조건을 추가 할 수 있습니다.

이 3 단계 프로세스를 수행하는 마이그레이션 스크립트에 대한 설명은 링크 된 블로그를 참조하십시오.


이것은 (내가 생각하는) 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

NOT NULL 제약 조건없이 열을 추가 한 다음 즉시 제약 조건을 추가하기 위해 열을 변경합니다. SQLite는 열을 추가하는 동안 분명히 매우 우려되지만 열 변경에 대해서는 그렇게 까다 롭지 않기 때문에 이렇게 할 수 있습니다. 이것은 내 책에서 분명한 디자인 냄새입니다.

확실히 해킹이지만 여러 마이그레이션보다 짧으며 프로덕션 환경에서 더 강력한 SQL 데이터베이스에서 계속 작동합니다.


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

Rails 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

참조 URL : https://stackoverflow.com/questions/3170634/how-to-solve-cannot-add-a-not-null-column-with-default-value-null-in-sqlite3

반응형