변경 열의 레일 마이그레이션


327

우리는 한 script/generate migration add_fieldname_to_tablename fieldname:datatype모델에 새 열을 추가하는 구문.

같은 줄에 열의 데이터 유형을 변경하는 스크립트 / 생성물이 있습니까? 아니면 바닐라 마이그레이션에 SQL을 직접 작성해야합니까?

나는에서 열을 변경하려면 datetimedate.

답변:


548

나는 이것이 효과가 있다고 생각한다.

change_column :table_name, :column_name, :date

13
@b_ayan : 내가 아는 한 마이그레이션 이름에서 마법 같은 단어는 "add"와 "remove"입니다.
Alex Korban

1
일종의 난간은 멍청하지만… 나는 대답을 이해하지만이 대답에 대한 의견은 이해하지 못합니다. :)
Alan H. 1

7
마이그레이션을 만들 때 이름을 지정하십시오 (예 : 위 질문에서 add_fieldname_to_tablename). "add"또는 "remove"로 시작하면 열을 추가하거나 제거하는 코드로 마이그레이션이 자동으로 채워져 해당 코드를 직접 작성할 수 있습니다.
Alex Korban

6
그것은 또한 당신이 일반적인 교체해야 염두에 둘 만하다 change분리와 행동 updown같은 행동을 change_column돌이킬 마이그레이션이며 롤 백업해야해야 오류를 올릴 것이다.
DaveStephens

1
@QPaysTaxes up에는 열을 변경하려는 내용이 포함되어야하고 down에는 해당 변경 사항을 되 돌리는 방법이 포함되어야합니다.
DaveStephens

98

테이블 내에서 변경할 열이 여러 개인 경우 블록을 사용할 수도 있습니다.

예:

change_table :table_name do |t|
  t.change :column_name, :column_type, {options}
end

자세한 내용은 Table 클래스API 설명서 를 참조하십시오.


88

명령 줄에서 마이그레이션을 수행하여이 모든 작업을 수행 할 수 있는지는 알 수 없지만 새 마이그레이션을 생성 한 다음 마이그레이션을 편집하여이 작업을 수행 할 수 있습니다.

tablename이 테이블 이름이고 fieldname이 필드 이름이고 날짜 / 시간을 변경하려는 경우 마이그레이션을 작성하여이를 수행 할 수 있습니다.

다음을 사용하여 새 마이그레이션을 만들 수 있습니다.

rails g migration change_data_type_for_fieldname

그런 다음 change_table을 사용하도록 마이그레이션을 편집하십시오.

class ChangeDataTypeForFieldname < ActiveRecord::Migration
  def self.up
    change_table :tablename do |t|
      t.change :fieldname, :date
    end
  end
  def self.down
    change_table :tablename do |t|
      t.change :fieldname, :datetime
    end
  end
end

그런 다음 마이그레이션을 실행하십시오.

rake db:migrate

32

이전 답변에서 알 수 있듯이 열 유형을 변경하려면 세 단계가 필요합니다.

1 단계:

이 코드를 사용하여 새 마이그레이션 파일을 생성하십시오.

rails g migration sample_name_change_column_type

2 단계:

/db/migrate폴더로 이동하여 작성한 마이그레이션 파일을 편집하십시오. 두 가지 솔루션이 있습니다.

  1. def change
        change_column(:table_name, :column_name, :new_type)
    end

2.

    def up
        change_column :table_name, :column_name, :new_type
    end

    def down
        change_column :table_name, :column_name, :old_type
    end

3 단계 :

이 명령을 수행하는 것을 잊지 마십시오 :

rake db:migrate

이 솔루션을 Rails 4에서 테스트했으며 제대로 작동합니다.


1
2 단계에서 rake db : rollback을 실행 한 후 첫 번째가 실패합니다. 두 번째를 확인하는 것이 좋습니다.
Feuda

마이그레이션 파일을 생성하지 않고 파일을 생성 한 후 편집 할 때 모든 작업을 수행 할 수있는 레일 규칙이 있습니까?
BKSpurgeon

@BKSpurgeon 예, 여기에서 설명서를 확인하십시오. edgeguides.rubyonrails.org/active_record_migrations.html
Aboozar Rajabi

12

레일 5

에서 레일 가이드 :

마이그레이션을 통해 Active Record가 되돌릴 방법을 모르는 작업을 수행하려면 다음을 사용할 수 있습니다 reversible.

class ChangeTablenameFieldname < ActiveRecord::Migration[5.1]
  def change
    reversible do |dir|
      change_table :tablename do |t|
        dir.up   { t.change :fieldname, :date }
        dir.down { t.change :fieldname, :datetime }
      end
    end
  end
end

8

마이그레이션을 생성하십시오.

rails g migration change_column_to_new_from_table_name

다음과 같이 마이그레이션을 업데이트하십시오.

class ClassName < ActiveRecord::Migration
  change_table :table_name do |table|
    table.change :column_name, :data_type
  end
end

그리고 마지막으로

rake db:migrate

2

마이그레이션을 사용하여 데이터 유형을 변경하는 다른 방법

1 단계: 마이그레이션을 사용하여 결함이있는 데이터 유형 필드 이름을 제거해야합니다.

전의:

rails g migration RemoveFieldNameFromTableName field_name:data_type

필드에 데이터 유형을 지정하는 것을 잊지 마십시오

2 단계 : 이제 올바른 데이터 유형으로 필드를 추가 할 수 있습니다

전의:

rails g migration AddFieldNameToTableName field_name:data_type

이제 테이블에 올바른 데이터 유형 필드, 해피 루비 코딩이 추가됩니다!


2

이것은 열의 데이터 유형에 기존 데이터에 대한 암시 적 변환이 있다고 가정합니다. 기존 데이터 String가 암시 적으로 새 데이터 유형으로 변환 될 수 있다고 가정 해 봅시다 Date.

이 상황에서는 데이터 변환으로 마이그레이션을 만들 수 있다는 것을 아는 것이 도움이됩니다. 개인적으로, 나는 이것을 모델 파일에 넣고 모든 데이터베이스 스키마가 마이그레이션되고 안정된 후에 제거하는 것을 좋아합니다.

/app/models/table.rb
  ...
  def string_to_date
    update(new_date_field: date_field.to_date)
  end

  def date_to_string
    update(old_date_field: date_field.to_s)
  end
  ...
    def up
        # Add column to store converted data
        add_column :table_name, :new_date_field, :date
        # Update the all resources
        Table.all.each(&:string_to_date)
        # Remove old column
        remove_column :table_name, :date_field
        # Rename new column
        rename_column :table_name, :new_date_field, :date_field
    end

    # Reversed steps does allow for migration rollback
    def down
        add_column :table_name, :old_date_field, :string
        Table.all.each(&:date_to_string)
        remove_column :table_name, :date_field
        rename_column :table_name, :old_date_field, :date_field
    end

0

기본값 을 편집하는 경우 답변을 완료하려면 다음을 수행하십시오.

레일 콘솔에서 :

rails g migration MigrationName

마이그레이션에서 :

  def change
    change_column :tables, :field_name, :field_type, default: value
  end

다음과 같이 보일 것입니다 :

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