레일에서 열 유형을 더 긴 문자열로 변경


90

첫 번째 마이그레이션에서 열에 content문자열 Activerecord를 선언 하여 주석 gem에 따라 string (255)으로 만들었습니다.

postgres를 사용하는 heroku에 앱을 푸시 한 후 255보다 긴 문자열을 콘텐츠에 양식에 입력하면 오류가 발생합니다.

PGError: ERROR: value too long for type character varying(255)

문제는 아마도 매우 긴 문자열을 포함하는 콘텐츠가 필요하다는 것입니다 (자유 텍스트, 수천 자일 수 있음)

  1. pg는 어떤 변수 (문자열이 적절하지 않음)를 허용합니까?
  2. 해당 열의 유형을 대체하기 위해 마이그레이션을 생성하는 방법

감사

답변:


216

text길이 제한이없는 문자열을 원한다면 Rails와 함께 사용해야합니다 . 다음과 같은 마이그레이션 :

def up
  change_column :your_table, :your_column, :text
end
def down
  # This might cause trouble if you have strings longer
  # than 255 characters.
  change_column :your_table, :your_column, :string
end

정리해야합니다. 당신은 :null => false그 끝에 또는 다른 옵션을 원할 수도 있습니다.

string명시 적 제한이없는 열 을 사용하면 Rails는 암시 적 :limit => 255. 그러나를 사용 text하면 데이터베이스가 지원하는 임의 길이 문자열 유형을 얻을 수 있습니다. PostgreSQL을 사용하면 varchar길이가없는 열 을 사용할 수 있지만 대부분의 데이터베이스는이를 위해 별도의 유형을 사용하며 Rails는 varchar길이 없이는 알지 못합니다 . PostgreSQL text에서 text 을 가져 오려면 Rails 에서 사용해야 합니다. 이 유형의 열 사이의 PostgreSQL의 차이 없습니다 text및 유형 중 하나 varchar(그러나 varchar(n) 입니다 다른). 당신은 PostgreSQL을 상단에 배치하는 경우 또한, 아무 소용에 이유가 없다 :string(AKA varchar) 모두에서, 데이터베이스 취급이 textvarchar(n)에 대한 추가 길이 제약을 제외하고는 내부적으로 동일합니다 varchar(n). 열 크기에 대한 외부 제약 (예 : 양식 897 / B의 필드 432가 23 자 길이라는 정부 양식)이있는 경우 에만 varchar(n)(AKA :string)를 사용해야합니다.

제쳐두고, string어디에서나 열을 사용하는 경우 항상 :limit한계가 있음을 상기시켜주는 것으로를 지정 해야하며 한계를 초과하지 않도록 모델에서 유효성을 검사해야합니다. 제한을 초과하면 PostgreSQL이 불만을 제기하고 예외를 발생시키고 MySQL은 조용히 문자열을 자르거나 불만을 제기합니다 (서버 구성에 따라 다름), SQLite는 그대로 전달하고 다른 데이터베이스는 다른 작업을 수행합니다 (아마도 불만이 제기 됨). .

또한 동일한 데이터베이스 (일반적으로 Heroku의 PostgreSQL) 위에 개발, 테스트 및 배포해야하며 동일한 버전의 데이터베이스 서버를 사용해야합니다. ActiveRecord가 사용자를 격리시키지 않는 데이터베이스 간에는 다른 차이점 (예 : GROUP BY의 동작)이 있습니다. 이미이 일을하고 있을지 모르지만 어쨌든 언급 할 것이라고 생각했습니다.


13
좋은 대답입니다. 참고 : Rails는 현재 change 메소드 ( guides.rubyonrails.org/migrations.html#using-the-change-method )를 사용하여 change_column을 지원하지 않습니다 . 메모리가 사용되면 되돌릴 수없는 마이그레이션이 생성됩니다. 업 / 다운 방법으로 구식 방식으로 수행하는 것이 좋습니다.
poetmountain

@BourbonJockey : 그것은 메이크업 감각 않는 change자동으로 유형 변경을 반대 할 수 없을 것입니다 및 마이그레이션 가이드 말하는가을 그 "이 방법은 (열 또는 테이블 추가) 건설 마이그레이션을 작성하기위한 선호 [변경 방법]"와 change_columnISN을 ' 당신이 가리키는 목록에서 당신이 옳다고 생각합니다. 나는 그것을 up/ down(에 대한 경고와 함께) 사용하도록 고쳤 down습니다.
MU이 너무 짧

4
다른 독자의 향후 참조를 위해 이러한 방식으로 Heroku의 Postgres에서 문자열을 텍스트로 변환해도 데이터가 손실되지 않습니다.
Marina Martin

2
@Dennis : 아마도 "동일한 데이터베이스를 사용하여 개발, 테스트 및 배포해야합니다"가 더 정확할 것입니다. 일반적인 문제는 사람들이 (어리석은) Rails 기본 SQLite 설정을 사용하고 다른 항목 위에 배포하면 사물이 무너진다는 것입니다. PostgreSQL은 여전히 ​​Heroku에서 기본적이고 가장 일반적인 옵션입니다.
MU이 너무 짧

3
참고로 길이가 지정되지 않은 필드가 255 자 여야한다는 Rails의 가정은 이상합니다. PostgreSQL에서 무제한 길이를 얻기 위해 사용할 필요 는 없습니다text . unconstrained를 사용할 수 있습니다 varchar. Rails는 PostgreSQL이 아닌이 홀수 제한을 부과하고 있습니다.
Craig Ringer

8

받아 들여진 대답은 훌륭하지만, 저와 같은 비전문가를 위해 원래 포스터 질문 파트 2를 더 잘 다룰 수있는 대답을 여기에 추가하고 싶었습니다.

  1. 해당 열의 유형을 대체하기 위해 마이그레이션을 생성하는 방법

스캐 폴드 마이그레이션 생성

콘솔에 입력하여 변경 사항을 보관할 마이그레이션을 생성 할 수 있습니다 ( table테이블 이름과 column열 이름을 바꾸면됩니다 ).

rails generate migration change_table_column

그러면 Rails 애플리케이션 / db / migrate / 폴더 내에 스켈레톤 마이그레이션이 생성됩니다. 이 마이그레이션은 마이그레이션 코드의 자리 표시 자입니다.

예를 들어 나는에서 열 유형을 변경하는 마이그레이션을 만들려 stringtext테이블라고 TodoItems에서 :

class ChangeTodoItemsDescription < ActiveRecord::Migration
  def change
     # enter code here
     change_column :todo_items, :description, :text
  end
end

마이그레이션 실행

열을 변경하는 코드를 입력했으면 다음을 실행하십시오.

rake db:migrate

마이그레이션을 적용하려면. 오류가있는 경우 언제든지 다음을 사용하여 변경 사항을 되돌릴 수 있습니다.

rake db:rollack

위아래 방법

새로운 방법 대신 허용되는 답변 참조 Up및 방법. Rails 3.2 이전 스타일의 Up 및 Down 방법은 새로운 Change 방법에 비해 몇 가지 장점을 제공했습니다. '위아래'피하십시오 . Rails 4 가 출시 된 이후 로이 오류를 피하는 데 사용할 수 있습니다 .DownChange ActiveRecord::IrreversibleMigration exceptionreversible

class ChangeProductsPrice < ActiveRecord::Migration
  def change
    reversible do |dir|
      change_table :products do |t|
        dir.up   { t.change :price, :string }
        dir.down { t.change :price, :integer }
      end
    end
  end
end

레일스 즐기기 :)

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.