Ruby on Rails 마이그레이션에서 데이터베이스 열의 이름을 바꾸려면 어떻게해야합니까?


답변:


2308
rename_column :table, :old_column, :new_column

이를 위해 별도의 마이그레이션을 만들고 싶을 것입니다. (원하는대로 이름을 바꾸십시오 FixColumnName.) :

script/generate migration FixColumnName
# creates  db/migrate/xxxxxxxxxx_fix_column_name.rb

그런 다음 원하는대로 마이그레이션을 편집하십시오.

# db/migrate/xxxxxxxxxx_fix_column_name.rb
class FixColumnName < ActiveRecord::Migration
  def self.up
    rename_column :table_name, :old_column, :new_column
  end

  def self.down
    # rename back if you need or do something else or do nothing
  end
end

Rails 3.1의 경우 :

updown방법이 여전히 적용 되는 동안 Rails 3.1은 change"데이터베이스를 마이그레이션하는 방법을 알고 별도의 다운 방법을 작성할 필요없이 마이그레이션이 롤백 될 때 데이터베이스를 되 돌리는 방법"을받습니다.

자세한 내용은 " 활성 레코드 마이그레이션 "을 참조하십시오.

rails g migration FixColumnName

class FixColumnName < ActiveRecord::Migration
  def change
    rename_column :table_name, :old_column, :new_column
  end
end

이름을 변경하기 위해 전체 열 묶음이 있거나 테이블 이름을 반복해서 반복 해야하는 경우 :

rename_column :table_name, :old_column1, :new_column1
rename_column :table_name, :old_column2, :new_column2
...

change_table물건을 조금 더 깔끔하게 유지 하는 데 사용할 수 있습니다 .

class FixColumnNames < ActiveRecord::Migration
  def change
    change_table :table_name do |t|
      t.rename :old_column1, :new_column1
      t.rename :old_column2, :new_column2
      ...
    end
  end
end

그런 다음 db:migrate평소와 같이 또는 비즈니스를 진행합니다.


레일 4의 경우 :

을 만드는 동안 Migration열을 바꾸기 위해, (4)는 생성 레일 change대신 방법 updown상기 섹션에 언급 한 바와 같이. 생성 된 change방법은 다음과 같습니다.

$ > rails g migration ChangeColumnName

다음과 유사한 마이그레이션 파일이 생성됩니다.

class ChangeColumnName < ActiveRecord::Migration
  def change
    rename_column :table_name, :old_column, :new_column
  end
end

24
self.down은 항상 self.up의 반대 여야 하므로 "필요하거나 다른 작업을하거나 아무것도하지 않는 경우"는 실제로 권장되지 않습니다. 그냥하세요 : rename_column : table_name, : new_column, : old_column
Luke Griffiths

3
당신이 한 일을 되 돌리는 것이 일반적인 관행이지만 " 항상 반대 해야한다" self.up고 말하지는 않을 것 입니다. 마이그레이션의 상황에 따라 다릅니다. "반대"를 두는 것만으로 "올바른"다운 마이그레이션이 아닐 수 있습니다. self.down
nowk

23
레일 3.1에서는 대체 할 수 def self.updef self.down함께 def change그것은 롤백하는 방법을 알 수 있습니다.
Turadg

2
Turadg-* 대부분의 롤백 방법을 알 수 있습니다. 이 change방법이 완전한 증거가 아니기 때문에 복잡한 마이그레이션 에 사용하는 방법 up과 경향이 있습니다 down.
JellyFishBoy

6
이름을 바꾸면 인덱스가 제거됩니까?
Sung Cho

68

내 생각에,이 경우에는을 사용 rake db:rollback하고 마이그레이션을 편집하고 다시 실행하는 것이 rake db:migrate좋습니다.

그러나 열에 데이터를 잃고 싶지 않은 경우을 사용하십시오 rename_column.


34
"하나의 팀"이라하더라도 다른 환경이나 여러 컴퓨터 등에서 여러 개의 앱 인스턴스가 실행중인 경우 편집 된 마이그레이션을 관리하는 것이 큰 어려움입니다. 내가하면 난 단지 마이그레이션을 편집 단지 를 생성하고 잘못 실현, 그리고 다른 곳에서는 아직 그대로 실행하지 않았습니다.
Yetanotherjosh

1
그 후 서버를 다시 시작해야했습니다.
Muhammad Hewedy

7
이 기술은 변경 사항이 아직 프로덕션 지사와 병합되지 않았고 데이터 지속성에 의존하지 않는 상황에서만 사용해야합니다. 대부분의 모든 프로덕션 환경에서 이는 선호되는 방법이 아닙니다.
Collin Graves

4
이런 종류의 일을 결코하지 마십시오.
new2cpp

4
팀에 다음과 같이 말하고 싶습니다 : '마이그레이션은 무료입니다.' 돌아가서 이미 실행 한 마이그레이션을 편집했습니다. 따라서 기존 마이그레이션을 편집하지 마십시오. 새로운 마이그레이션을 사용하여 스키마를 변경하십시오. 왜냐하면 ... '마이그레이션은 무료입니다!' (그것은 엄격하게 사실은 아니지만 요점을
밝힙니다

31

열이 이미 데이터로 채워져 있고 프로덕션 환경에있는 경우 마이그레이션을 기다리는 동안 프로덕션에서 다운 타임을 피하기 위해 단계별 접근 방식을 권장합니다.

먼저 새로운 이름으로 열을 추가하고 이전 열 이름의 값으로 채울 수 있도록 db 마이그레이션을 만듭니다.

class AddCorrectColumnNames < ActiveRecord::Migration
  def up
    add_column :table, :correct_name_column_one, :string
    add_column :table, :correct_name_column_two, :string

    puts 'Updating correctly named columns'
    execute "UPDATE table_name SET correct_name_column_one = old_name_column_one, correct_name_column_two = old_name_column_two"
    end
  end

  def down
    remove_column :table, :correct_name_column_one
    remove_column :table, :correct_name_column_two
  end
end

그런 다음 그 변경 사항을 커밋하고 변경 사항을 프로덕션에 적용합니다.

git commit -m 'adding columns with correct name'

그런 다음 커밋이 프로덕션으로 푸시되면 실행됩니다.

Production $ bundle exec rake db:migrate

그런 다음 이전 열 이름을 참조한 모든보기 / 컨트롤러를 새 열 이름으로 업데이트했습니다. 내 테스트 스위트를 실행하고 변경 사항을 커밋하십시오. (로컬에서 작동하고 모든 테스트를 먼저 통과했는지 확인한 후!)

git commit -m 'using correct column name instead of old stinky bad column name'

그런 다음 그 커밋을 프로덕션에 푸시합니다.

이 시점에서 마이그레이션 자체와 관련된 모든 종류의 다운 타임에 대한 걱정없이 원본 열을 제거 할 수 있습니다.

class RemoveBadColumnNames < ActiveRecord::Migration
  def up
    remove_column :table, :old_name_column_one
    remove_column :table, :old_name_column_two
  end

  def down
    add_column :table, :old_name_column_one, :string
    add_column :table, :old_name_column_two, :string
  end
end

그런 다음이 최신 마이그레이션을 프로덕션으로 푸시 bundle exec rake db:migrate하고 백그라운드에서 실행 하십시오.

나는 이것이 프로세스에 조금 더 관여한다는 것을 알고 있지만 프로덕션 마이그레이션에 문제가있는 것보다 오히려이 작업을 수행하고 싶습니다.


2
나는 이것에 대한 생각을 좋아하고, 당신의 응답을 +1하지만 데이터 업데이트는 레일을 통과하고 한 번에 한 행씩 수행하기 때문에 실행하는 데 시간이 오래 걸릴 것입니다. 올바르게 명명 된 열을 업데이트하기 위해 원시 SQL 문으로 마이그레이션을 훨씬 빠르게 실행할 수 있습니다. 예를 들어, 첫 번째 db 마이그레이션 스크립트에서 중복 열 이름을 추가 한 후 execute "Update table_name set correct_name_column_one = old_name_column_one"
Gui Weinmann

1
@ mr.ruh.roh ^ 완전히 동의합니다. 효율적인 단일 SQL 문을 반영하도록 편집했습니다. 위생 검사 감사합니다.
Paul Pettengill

2
새 테이블로 이동하고 새 테이블을 사용하도록 코드를 업데이트하는 사이의 항목은 어떻게됩니까? 잠재적으로 마이그레이션되지 않은 데이터가 남지 않았습니까?
Stefan Dorunga

1
이것이 '안전한'답변이지만 불완전하다고 생각합니다. 여기 많은 사람들이 이것을하지 않는다고 말합니다-왜? 데이터 지속성. 그리고 그것은 유효합니다. 아마도 가장 고통스러운 목표는 새로운 필드를 생성하고 이전 열의 데이터로 채우고 컨트롤러를 조정하는 것입니다. 이전 열을 삭제하려면 반드시보기를 편집해야합니다. 그것들을 유지하는 비용은 여분의 DB 공간과 컨트롤러의 중복 노력입니다. 따라서 절충점은 분명합니다.
Jerome


18

아래 명령을 실행하여 마이그레이션 파일을 작성하십시오.

rails g migration ChangeHasedPasswordToHashedPassword

그런 다음 db/migrate폴더에 생성 된 파일에 다음과 같이 작성하십시오 rename_column.

class ChangeOldCoulmnToNewColumn < ActiveRecord::Migration
  def change
     rename_column :table_name, :hased_password, :hashed_password
  end
end

14

API에서 :

rename_column(table_name, column_name, new_column_name)

열 이름은 바뀌지 만 유형과 내용은 동일하게 유지됩니다.


12

일부 버전의 Ruby on Rails는 업 / 다운 방법으로 마이그레이션을 지원하며, 마이그레이션에 업 / 다운 방법이 있으면 다음을 수행하십시오.

def up
    rename_column :table_name, :column_old_name, :column_new_name
end

def down
    rename_column :table_name, :column_new_name, :column_old_name
end

당신이있는 경우 change마이그레이션에 방법을, 다음 :

def change
    rename_column :table_name, :column_old_name, :column_new_name
end

자세한 정보는 Ruby on Rails-마이그레이션 또는 활성 레코드 마이그레이션으로 이동할 수 있습니다 .


11

코드가 다른 코드와 공유되지 않으면 rake db:rollback 마이그레이션 및에서 열 이름을 편집하는 것이 가장 좋습니다 rake db:migrate. 그게 다야

그리고 다른 마이그레이션을 작성하여 열 이름을 바꿀 수 있습니다.

 def change
    rename_column :table_name, :old_name, :new_name
  end

그게 다야.


rake db:rollback좋은 제안입니다. 그러나 당신이 말했듯이, 이주가 아직 추진되지 않은 경우에만.
danielricecodes가

9

대안 옵션으로, 마이그레이션 아이디어와 결혼하지 않은 경우 ActiveRecord에는 Datamapper 스타일의 이름 변경을 자동으로 처리하는 매력적인 보석이 있습니다. 모델의 열 이름을 변경하고 ( model.rb 의 맨 아래에 Model.auto_upgrade! 를 배치했는지 확인 ) viola! 데이터베이스가 즉시 업데이트됩니다.

https://github.com/DAddYE/mini_record

참고 : 충돌을 방지하려면 db / schema.rb압축 해제 해야합니다.

여전히 베타 단계에 있으며 분명히 모든 사람에게 적합하지는 않지만 여전히 매력적인 선택입니다 (현재 문제가없는 두 가지 사소한 프로덕션 앱에서 사용하고 있습니다)


8

열 이름을 전환해야하는 경우 중복 열 이름 오류 를 방지하기 위해 자리 표시자를 만들어야합니다 . 예를 들면 다음과 같습니다.

class SwitchColumns < ActiveRecord::Migration
  def change
    rename_column :column_name, :x, :holder
    rename_column :column_name, :y, :x
    rename_column :column_name, :holder, :y
  end
end

7

현재 데이터가 중요하지 않은 경우 다음을 사용하여 원래 마이그레이션을 중단 할 수 있습니다.

rake db:migrate:down VERSION='YOUR MIGRATION FILE VERSION HERE'

따옴표없이 원래 마이그레이션을 변경하고 다음을 수행하여 다시 마이그레이션을 다시 실행하십시오.

rake db:migrate

6

간단히 새로운 마이그레이션을 생성하고 블록 단위 rename_column로 아래와 같이 사용하십시오 .

rename_column :your_table_name, :hased_password, :hashed_password


5

수동으로 아래 방법을 사용할 수 있습니다.

다음과 같이 마이그레이션을 수동으로 편집 할 수 있습니다.

  • 열다 app/db/migrate/xxxxxxxxx_migration_file.rb

  • 업데이트 hased_passwordhashed_password

  • 아래 명령을 실행하십시오.

    $> rake db:migrate:down VERSION=xxxxxxxxx

그런 다음 마이그레이션을 제거합니다.

$> rake db:migrate:up VERSION=xxxxxxxxx

업데이트 된 변경 사항으로 마이그레이션을 추가합니다.


열이 이미 활성 상태 인 경우 데이터가 손실 될 수 있으므로 안전하지 않습니다. 그러나 새로운 열 및 / 또는 테이블에 대해 할 수 있습니다.
Tejas Patel

5

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

rails g migration FixName

# db / migrate / xxxxxxxxxx.rb를 작성합니다

원하는대로 마이그레이션을 편집하십시오.

class FixName < ActiveRecord::Migration
  def change
    rename_column :table_name, :old_column, :new_column
  end
end

5

운영 rails g migration ChangesNameInUsers (또는 이름을 지정하려는 모든 것)

방금 생성 된 마이그레이션 파일을 열고 메소드에서 (와 사이 def changeend) 이 행을 추가하십시오 .

rename_column :table_name, :the_name_you_want_to_change, :the_new_name

파일을 저장하고 rake db:migrate콘솔에서 실행하십시오.

schema.db데이터베이스에서 이름이 실제로 변경 되었는지 확인하려면를 확인하십시오 !

도움이 되었기를 바랍니다 :)


5

키스 합시다 . 세 단계 만 거치면됩니다. 다음은 Rails 5.2에서 작동합니다 .

1 . 마이그레이션 만들기

  • rails g migration RenameNameToFullNameInStudents

  • rails g RenameOldFieldToNewFieldInTableName그런 식으로 나중에 코드베이스를 유지 관리하는 사람들에게 완벽하게 분명합니다. (테이블 이름에 복수를 사용하십시오).

2. 마이그레이션 편집

# I prefer to explicitly write the위로 and아래로methods.

# ./db/migrate/20190114045137_rename_name_to_full_name_in_students.rb

class RenameNameToFullNameInStudents < ActiveRecord::Migration[5.2]
  def up
    # rename_column :table_name, :old_column, :new_column
    rename_column :students, :name, :full_name
  end

  def down
            # Note that the columns are reversed
    rename_column :students, :full_name, :name
  end
end

3. 마이그레이션을 실행하십시오.

rake db:migrate

그리고 당신은 경주에서 벗어났습니다!


4
$:  rails g migration RenameHashedPasswordColumn
invoke  active_record
      create    db/migrate/20160323054656_rename_hashed_password_column.rb

해당 마이그레이션 파일을 열고 다음과 같이 파일을 수정하십시오 (원본을 입력하십시오 table_name)

class  RenameHashedPasswordColumn < ActiveRecord::Migration
  def change
    rename_column :table_name, :hased_password, :hashed_password
  end
end

4
 def change
    rename_column :table_name, :old_column_name, :new_column_name
  end

3

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

$:> rails g migration Fixcolumnname

마이그레이션 파일 (XXXXXfixcolumnname.rb)에 코드를 삽입하십시오 .

class Fixcolumnname < ActiveRecord::Migration
  def change
    rename_column :table_name, :old_column, :new_column
  end
end

2

Ruby on Rails 콘솔을 열고 다음을 입력하십시오.

ActiveRecord::Migration.rename_column :tablename, :old_column, :new_column

2

이를 수행하는 두 가지 방법이 있습니다.

  1. 이 유형에서는 롤백 할 때 역 코드를 자동으로 실행합니다.

    def change
      rename_column :table_name, :old_column_name, :new_column_name
    end
  2. 이 유형에서는 다음 rake db:migrate과 같은 경우 up 메소드를 실행하고 다음과 같은 경우 down 메소드를 실행합니다 rake db:rollback.

    def self.up
      rename_column :table_name, :old_column_name, :new_column_name
    end
    
    def self.down
      rename_column :table_name,:new_column_name,:old_column_name
    end

2

나는 레일즈 5.2에 있으며, 고안 사용자의 열 이름을 바꾸려고합니다.

rename_column비트는 나를 위해 일하지만, 단수 :table_name줬어요 오류 "사용자 테이블을 찾을 수 없음". 복수가 나를 위해 일했습니다.

rails g RenameAgentinUser

그런 다음 마이그레이션 파일을 다음으로 변경하십시오.

rename_column :users, :agent?, :agent

어디 요원? 이전 열 이름입니다.


0

업데이트 -create_table의 가까운 사촌은 change_table이며 기존 테이블을 변경하는 데 사용됩니다. create_table과 비슷한 방식으로 사용되지만 블록에 생성 된 객체는 더 많은 트릭을 알고 있습니다. 예를 들면 다음과 같습니다.

class ChangeBadColumnNames < ActiveRecord::Migration
  def change
    change_table :your_table_name do |t|
      t.rename :old_column_name, :new_column_name
    end
  end
end

이 방법은 다음과 같은 다른 변경 방법으로 수행하는 경우보다 효율적입니다. remove / add index / remove index / add column, 예 :

# Rename
t.rename :old_column_name, :new_column_name
# Add column
t.string :new_column
# Remove column
t.remove :removing_column
# Index column
t.index :indexing_column
#...

0

명령을 사용하여 마이그레이션을 생성하십시오.

rails g migration rename_hased_password

그 후 마이그레이션 방법 변경 방법에서 다음 줄 추가

rename_column :table, :hased_password, :hashed_password

이것은 트릭을해야합니다.


0

Rails 5 마이그레이션 변경

예 :

레일스 g 모델 학생 student_name : 문자열 연령 : 정수

student_name 열을 이름 으로 변경하려는 경우

참고 :- 레일을 실행하지 않으면 db : migrate

다음 단계를 수행 할 수 있습니다

rails d 모델 학생 student_name : 문자열 연령 : 정수

생성 된 마이그레이션 파일이 제거됩니다. 이제 열 이름을 수정할 수 있습니다

레일 g 모델 학생 이름 : 문자열 연령 : 정수

마이그레이션 한 경우 (rails db : migrate) 다음 옵션을 사용하여 열 이름을 변경하십시오.

레일 g 마이그레이션 RemoveStudentNameFromStudent student_name : string

레일 g 마이그레이션 AddNameTo 학생 이름 : string


안됩니다 : rails g migration RemoveStudentNameFromStudentS student_name:string(학생들은 복수형입니까)?
BKSpurgeon

또한 이것은 위험합니다. 열의 이름이 바뀌지 않지만 완전히 제거 된 다음 다시 읽습니다. 데이터는 어떻게 되나요? 이것은 사용자가 원하는 것이 아닐 수도 있습니다.
BKSpurgeon
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.