RailsのMigration
- 2006.07.21
- Ruby/Rails, 勉強会資料
なんですかこれは
データベース構造をバージョン管理する仕組み
SQLではなくRubyのコードでデータベース構造を記述することによって抽象化
- 本番環境への変更の適用漏れがなくなる
- ほかの開発環境や検証環境への変更の適用がバッチリ
- 必要があれば以前のバージョンに戻せる
- 複数のデータベースエンジンへの対応が簡単にできる
- MySQL, PostgreSQL, SQLite, SQL Server, Sybase, Oracle (メジャーなものはDB2以外ぜんぶだって)
どうつかいますか
$ svn up
$ rake migrate
セットで使う。
これで手元の開発環境のソースコードとデータベースの構造が最新のものになる。
仕組み
schema_infoというテーブルとMigration定義ファイルの名前でバージョン管理
Migration関連の操作
rake db:schema:dump (rake db_schema_dump)
db/schema.rbにデータベース構造をダンプする。
# This file is autogenerated. Instead of editing this file, please use the
# migrations feature of ActiveRecord to incrementally modify your database, and
# then regenerate this schema definition.
ダンプされたファイルの最初の三行。 このファイルを編集して使うんじゃなくてMigrationを使ってくれと言っている。
既存のデータベースがあって途中からMigrationをはじめる場合はこのファイルを元に最初の定義ファイルを作っていくと良い。
このときunsignedなど抽象表現でサポートしてない構造は消えてしまうので注意。
rake db:schema:load (rake db_schema_import)
db/schema.rbの内容をデータベースに反映する。
普通は使わない?
./script/generate migration MigrationName
Migration定義ファイルの雛形を作成する。
class Hoge < ActiveRecord::Migration
def self.up
end
def self.down
end
end
rake migrate
Migration定義ファイルの内容をすべて開発用のデータベースに反映する。
rake migrate VERSION=1
Migration定義ファイルの内容に従ってデータベースの構造を指定されたバージョンの状態に戻す
※バージョンを戻す場合はsvnより先にmigrate(定義ファイルがなくなると元に戻せない)
rake migrate RAILS_ENV=production
本番環境へのMigration
Migration定義ファイルの書き方
ファイル名とバージョン
ファイル名の先頭にバージョン番号を入れる
001_create_gadgets.rb
002_migration_test.rb
ファイル名とクラス名はそろえないとダメ
ファイル名のバージョン番号は現在あるファイルをもとに作られるので、複数人で開発してるとバッティングしてしまうこともあり得る そういう場合はバージョン戻したりして適宜調整。
self.upとself.down
バージョンを進めるときにself.upが実行されて、バージョンを戻すときにself.downが実行される。
この整合性が取れてないとバージョンを戻したときにおかしなことになる可能性がある。
できること一覧
- create_table(name, options)
- drop_table(name)
- rename_table(old_name, new_name)
- add_column(table_name, column_name, type, options)
- rename_column(table_name, column_name, new_column_name)
- change_column(table_name, column_name, type, options)
- remove_column(table_name, column_name)
- add_index(table_name, column_name, index_type)
- remove_index(table_name, column_name)
カラムの型
抽象表現 | Ruby型 | PostgreSQL型 | MySQL型 |
---|---|---|---|
:primary_key | Fixnum | serial | primarykeyint(11)DEFAULTNULLauto_incrementPRIMARYKEY |
:string | String | charactervarying(255) | varchar(255) |
:text | String | text | text |
:integer | Fixnum | integer | int(11) |
:float | Float | float | float |
:datetime | Time | timestamp | datetime |
:timestamp | Time | timestamp | datetime |
:time | Time | timestamp | datetime |
:date | Date | date | date |
:binary | String | bytea | blob |
:boolean | Object | boolean | tinyint(1) |
- MySQLの数値型
- :integer, :limit => 3 → tinyint
- :integer, :limit => 5 → smallint
- :integer, :limit => 7 → mediumint
- :integer, :limit => 10 → int
- :integer, :limit => 20 → bigint
unsignedにはできないぽい?
BLOB型とかも桁数指定でtinyblobとかになります。
カラムのオプション
:limit | 数値で桁数指定 |
:default | デフォルト値を指定 |
:null | true or false |
生SQLも
- execute(sql)
どうしてもunsignedつけたいときとか。
スキーマ変更以外のデータメンテにも
どうぞ
参考にしたページ
- ヽ( ・∀・)ノくまくまー(2005-08-17) Migration
- Class: ActiveRecord::Migration:
- UsingMigrations in Ruby on Rails
- Rails Migration Cheat Sheet
おまけトピックス
本番運用
なめてると意外と難しい
httpd
- Apache+Fast-CGI
- 設定かなりめんどい
- 2.0だと不安定
- とはいえApacheで動かさざるを得ない場合は多い
- lighttpd+Fast-CGI
- 設定それなりにめんどい
- 事実上Railsの標準?
- mongrel
- 簡単ではやい(らしい)
- 台頭中
- WEBrick
- 簡単だしパフォーマンスもそこそこ
- アクセスが少なければコレで十分
- Apache+CGI
- ナローバンドの時代に逆戻りしたかのような懐かしさを覚える
- ダメ、絶対
データベース
- development,test,productionの環境の違いに注意
- database.ymlはリポジトリに入れるべきなんだろうか
- 多少の学習コストを払ってもMigrationを使ったほうがいい
Railsバージョン互換性問題
Railsのバージョンが変わるとアプリが動かなくなる。 freezeしとくとvender以下に特定バージョンのRailsを置いておけるので平気。
- rake rails:freeze:gems - 現在インストールされてるバージョンを使用。普段はたぶんこれ。
- rake rails:freeze:edge - RailsリポジトリのHEADを持ってくる。たぶん実験とかするときに使う。
- rake rails:freeze:edge TAG=rel_1-1-2 - Railsのリポジトリから指定タグのバージョンを持ってくる
Capistrano
- 古いディストリだとrubyのopensslのライブラリが鬼門な気がする
- database.ymlリポジトリからいつも持ってくる
- すべてのサーバにRubyとrakeとrailsを入れないとダメでユーザも作らないとダメなのがめんどい
- けどRailsアプリをスケールアウトするならコレ
開発環境どうする
- ローカルで編集してアップ
- scp
- rsync
- リモートのファイルを直接編集
- エディタのリモートファイル編集機能
- samba
- そもそもLinuxマシンをクライアントに
- WindowsにRailsを入れる
- Cygwin上に入れたものはほぼ問題なく動くようだ
- ローカル開発万歳
- Mac Bookを買う