DB Migration in Rails 3

Rails 3.1로 업그레이드되면서, 마이그레이션 작업에 약간의 추가 메소드가 생겼습니다.


$ rails g model post title:string body:text

와 같이 명령을 수행할 때 만들어지는 마이그레이션 루비 파일의 내용을 보면 이전 up/down 메소드 대신 change 메소드 하나만 보이게 됩니다. 개발자로 하여금 코딩 시간을 줄일 수 있고 좀 더 지능적인 프레임워크로 진화하고 있는 느낌이 듭니다.

# in Rails 2.x
class CreatePosts < ActiveRecord::Migration
   def self.up
      create_table :posts do |t|
         t.string :title
         t.text :body
         t.timestamps

      end
   end

   def self.down
      drop_table :posts
   end

end

# in Rails 3.1
class CreatePosts < ActiveRecord::Migration

   def change
      create_table :posts do |t|
         t.string :title
         t.text :body
         t.timestamps
      end
   end

end

마이그레이션을 위해 실질적인 테이블을 물리적으로 만들기 위해서는 다음의 명령이 실행되어야 합니다


$ rake db:migration

와 같이 실행하면 아직 마이크레이션 되지 않은 마이그레이션 루비 파일들을 불러들여 실행하게 됩니다. 이러한 마이그레이션 루비파일들은 파일명 앞에 타임스탬프가 찍혀 있는데, 이렇게 마이그레이션 파일이 rake되면 해당 파일의 파일명 앞에 있는 타임스탬프가 schema_migrations 라는 테이블에 추가됩니다. 그래서 마이그레이션 rake 명령이 실행될 때 이 테이블을 검색해서 테이블에 파일의 타임스탬프가 있으면 수행을 하지 않게 됩니다.


$ rake db:migration:status

위의 명령을 수행하면 지금까지 수행되었던 마이그레이션 이력을 일견에 볼 수 있어 어디까지 마이그레이션 작업이 수행되었는지도 쉽게 알 수 있습니다.

자, 이렇게 마이그레이션을 위한 rake 작업을 한 후에 테이블을 수정할 상황이 발생할 경우, rake 작업을 취소하고 데이터베이스내 태이블을 롤백해야 하는데, 이 과정은 다음과 같습니다.


$ rake db:rollback

마이그레이션 작업이 취소되고 테이블이 롤백됩니다.

이후에 마이그레이션을 위한 루비 파일을 수정하고 다시 위에서 언급한 바와 같이 마이그레이션 rake 작업을 수행하면 됩니다.

때로는 특정 마이그레이션 파일을 롤백하고 싶은 경우가 있는데, 다음과 같이 VERSION= 다음에 해당 파일명 앞의 타임스탬프 숫자만을 추가해 주면 됩니다.

$ rake db:migrate:down VERSION=20080906120000

Rails 3.1의 change 메소드는 이러한 롤백과정에서 자동으로 반대기능을 하는 메소드를 추정해서 실행하게 됩니다.


$ rake db:migrate (in /home/rohit/code/migrahedron)

== CreatePosts: migrating ===========================
-- create_table(:posts)
-> 0.0012s

== CreatePosts: migrated (0.0013s) =====================

$ rake db:rollback (in /home/rohit/code/migrahedron)

== CreatePosts: reverting("posts")
-> 0.0007s

== CreatePosts: reverted (0.0008s)======================

그러나 자동으로 역방향 메소드를 실행하지 못하고 에러가 발생하는 경우가 있습니다.


class RemoveTitleFromPost < ActiveRecord::Migration
   def change
      remove_column :posts, :title
   end
end

$ rake db:rollback이런 경우에는 역방향 메소드 add_column이 호출될 때 정보가 부족하여, 즉, 데이터형에 대한 정보가 없기 때문에 에러가 발행하게 되는 것입니다.


== RemoveTitleFromPost: reverting =========================
rake aborted!

An error has occurred, this and all later migrations canceled:
ActiveRecord::IrreversibleMigration
(See full trace by running task with --trace)

이럴 경우에는 이전 버젼에서와 같이 up 또는 down 인스턴스 메소드를 구현해서 마이그레이션 루비 스크립트를 작성해 주어야 합니다.


class RemoveTitleFromPost < ActiveRecord::Migration
   def up
      remove_column :posts, :title
   end
   def down
      add_column :posts,:title,:string
   end
end

주의: self.up / self.down 클래스 메소드가 아니고 up / down 인스턴스 메소드로 작성해 주어야 합니다.

글쓴이: 최효성

외과전문의,웹프로그래밍,컴퓨터 일러스트레이션 / Surgeon, Medical Illustration, Web Programmer

4 thoughts on “DB Migration in Rails 3”

  1. 루비온레일 자료를 찾아보다가 선생님이 올리신 자료를 보고 글남깁니다.
    저는 루비온레일을 이제 막 시작하려는 웹개발자인데 자료를 찾는일이 쉽지가 않네요.
    한국의 자료는 거의 대부분 2006년 2007년도 자료인데 루비온레일은 지난 버젼의 명령어를 허용하지 않기때문에 최신버젼을 받아서 예전 자료로 공부를 하다보니 애를 많이 먹었습니다. 혹시 한국에 루비온레일 관련해서 아직도 활발하게 활동중인 웹커뮤니티나 포럼이 있는지 궁금해서 여쭤봅니다. 미국에는 몇군데 있는것 같은데 사실 코딩을 하면서 정작 막히는건 상세히 설명을 해놓지 않아 답답할때가 너무 많습니다.
    특히 윈도우 환경에서 아파치와 연동하는 부분은 하다가 결국 포기를 했습니다.
    지금 다시 리눅스를 버추얼머신에 깔아서 다시 처음부터 설치를 시도하려고 합니다.
    선생님이 올려주신 블로그 감사히 보고 갑니다.
    그럼 좋은 하루 되세요~ 루비온레일 개발자 화이팅!!!

  2. 레일스는 엄청난 속도로 성장하고 있는 프레임워크입니다. 따라서 번역판을 찾을 시간이면 이미 레일스 프레임워크는 한참 멀리 앞서가 있죠. 저도 전문 프로그래머가 아니라서 국내 레일스 커뮤니티에 대해서 전문성을 가지고 설명드릴 수 없지만, 구글그룹에 한국루비사용자모임이 있고, 그외에는 잘 모르겠습니다. 혼자서 독학하는 아마츄어 정도 수준입니다. 혹, 페이스북을 하시면 Ruby on Rails, Korea라는 그룹이 있습니다. 여기에 29명정도 관심있는 분들이 있고, 제가 레일스 공부하면서 초보자들에게 도움이 될만한 내용이 있으면 함께 공유하고 있습니다.

  3. 와우! 답변 감사합니다^^ 페이스북의 Ruby on Rails, Korea에 Join Request 보냈어요^^ 정보를 얻는것보다 중요한건 함께 상의할 사람이 있다는게 참 중요한거 같아요^^ 누군가에게 문제를 털어놓으면 어느새 스스로 정리가 되는데 저도 혼자 하다보니 가끔은 했던거 또하고 그냥 같은 길을 돌고 도는 기분이 들어서요 ㅋㅋ 선생님 답변에 갑자기 많은 부분이 정리가 되는듯 합니다. 감사합니다^^

답글 남기기

아래 항목을 채우거나 오른쪽 아이콘 중 하나를 클릭하여 로그 인 하세요:

WordPress.com 로고

WordPress.com의 계정을 사용하여 댓글을 남깁니다. 로그아웃 / 변경 )

Twitter 사진

Twitter의 계정을 사용하여 댓글을 남깁니다. 로그아웃 / 변경 )

Facebook 사진

Facebook의 계정을 사용하여 댓글을 남깁니다. 로그아웃 / 변경 )

Google+ photo

Google+의 계정을 사용하여 댓글을 남깁니다. 로그아웃 / 변경 )

%s에 연결하는 중