RailsでMySQLにマイグレーションでテーブルを作成してみる
RailsでMySQLにスキーマファイルからテーブルを作成してみるの続き
migrateのディレクトリが無ければ作っておく。
$ mkdir db/migrate
また、前回のテーブルが残っているので、一旦まっさらな状態にしておく。
$ rake db:drop $ rake db:create
空のcreate_table
何もカラムを書かずにテーブルを作成してみる。
$ vi db/migrate/1_create_table_first.rb
class CreateTableFirst < ActiveRecord::Migration def change create_table :sample1 do |t| end end end
db:migrateを実施するとDBに反映される。
$ rake db:migrate
sample1のテーブルが作成され、テーブルにはidというカラムが自動で追加される。
また、バージョン番号1も追加される。
mysql> show tables; +------------------------------------+ | Tables_in_sample_mysql_development | +------------------------------------+ | sample1 | | schema_migrations | +------------------------------------+ mysql> desc sample1; +-------+---------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-------+---------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | +-------+---------+------+-----+---------+----------------+ mysql> select * from schema_migrations; +---------+ | version | +---------+ | 1 | +---------+
schema.rbも自動で更新される。
$ cat db/schema.rb ActiveRecord::Schema.define(version: 1) do create_table "sample1", force: true do |t| end end
created_at/updated_at
t.timestampsを指定すると、created_atとupdated_atのカラムが追加される。
$ vi db/migrate/2_create_table_timestamps.rb
class CreateTableTimestamps < ActiveRecord::Migration def change create_table :sample2 do |t| t.timestamps end end end
$ rake db:migrate
mysql> desc sample2; +------------+----------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +------------+----------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | created_at | datetime | YES | | NULL | | | updated_at | datetime | YES | | NULL | | +------------+----------+------+-----+---------+----------------+
様々な型
様々な型のカラムを作成してみる。
$ vi db/migrate/3_create_table_types.rb
class CreateTableTypes < ActiveRecord::Migration def change create_table :sample3 do |t| t.string :column01 # 文字列 t.text :column02 # 長い文字列 t.integer :column03 # 整数 t.float :column04 # 浮動小数 t.decimal :column05 # 精度の高い小数 t.datetime :column06 # 日時 t.timestamp :column07 # より細かい日時 t.time :column08 # 時間 t.date :column09 # 日付 t.binary :column10 # バイナリデータ t.boolean :column11 # Boolean型 end end end
$ rake db:migrate
mysql> desc sample3; +----------+---------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +----------+---------------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | column01 | varchar(255) | YES | | NULL | | | column02 | text | YES | | NULL | | | column03 | int(11) | YES | | NULL | | | column04 | float | YES | | NULL | | | column05 | decimal(10,0) | YES | | NULL | | | column06 | datetime | YES | | NULL | | | column07 | datetime | YES | | NULL | | | column08 | time | YES | | NULL | | | column09 | date | YES | | NULL | | | column10 | blob | YES | | NULL | | | column11 | tinyint(1) | YES | | NULL | | +----------+---------------+------+-----+---------+----------------+
様々なオプション
様々なカラムのオプションを指定してみる。
$ vi db/migrate/4_create_table_options.rb
class CreateTableOptions < ActiveRecord::Migration def change create_table :sample4 do |t| t.string :column01, :limit => 100 # カラムの桁数 t.integer :column02, :default => 200 # デフォルトの値 t.float :column03, :null => false # nullを許可するか end end end
$ rake db:migrate
mysql> desc sample4; +----------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +----------+--------------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | column01 | varchar(100) | YES | | NULL | | | column02 | int(11) | YES | | 200 | | | column03 | float | NO | | NULL | | +----------+--------------+------+-----+---------+----------------+
カラムの変更
カラムを色々変更してみる。
$ vi db/migrate/5_change_table_columns.rb
class ChangeTableColumns < ActiveRecord::Migration def change # カラムを追加 add_column :sample3, :column99, :string # カラムを変更 change_column :sample3, :column01, :integer # カラムを変更(各種オプション指定) change_column :sample3, :column02, :string, :limit => 200, :default => 'hello', :null => false # カラムの初期値を変更 change_column_default :sample3, :column03, 300 # カラムの名前を変更 rename_column :sample3, :column04, :column44 # カラムを削除 remove_column :sample3, :column05 # カラムをまとめて削除 remove_columns :sample3, :column06, :column07, :column08, :column09, :column10 end end
$ rake db:migrate
mysql> desc sample3; +----------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +----------+--------------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | column01 | int(11) | YES | | NULL | | | column02 | varchar(200) | NO | | hello | | | column03 | int(11) | YES | | 300 | | | column44 | float | YES | | NULL | | | column11 | tinyint(1) | YES | | NULL | | | column99 | varchar(255) | YES | | NULL | | +----------+--------------+------+-----+---------+----------------+
インデックスの追加
インデックスを追加してみる。
$ vi db/migrate/6_add_index.rb
class AddIndex < ActiveRecord::Migration def change # インデックスを追加 add_index :sample4, :column01 # ユニークインデックスの追加 add_index :sample4, :column02, :unique => true # インデックス名を指定 add_index :sample4, :column03, :name => 'column03_index' # 複数カラムのインデックスを追加 add_index :sample4, [:column02, :column03] end end
$ rake db:migrate
mysql> show index from sample4; +---------+------------+----------------------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+ | Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | +---------+------------+----------------------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+ | sample4 | 0 | PRIMARY | 1 | id | A | 0 | NULL | NULL | | BTREE | | | sample4 | 0 | index_sample4_on_column02 | 1 | column02 | A | 0 | NULL | NULL | YES | BTREE | | | sample4 | 1 | index_sample4_on_column01 | 1 | column01 | A | 0 | NULL | NULL | YES | BTREE | | | sample4 | 1 | column03_index | 1 | column03 | A | 0 | NULL | NULL | | BTREE | | | sample4 | 1 | index_sample4_on_column02_and_column03 | 1 | column02 | A | 0 | NULL | NULL | YES | BTREE | | | sample4 | 1 | index_sample4_on_column02_and_column03 | 2 | column03 | A | 0 | NULL | NULL | | BTREE | | +---------+------------+----------------------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
最後に
schema.rbの中身がどうなってるか確認すると、下記のように更新されている。
$ cat db/schema.rb
ActiveRecord::Schema.define(version: 6) do create_table "sample1", force: true do |t| end create_table "sample2", force: true do |t| t.datetime "created_at" t.datetime "updated_at" end create_table "sample3", force: true do |t| t.integer "column01" t.string "column02", limit: 200, default: "hello", null: false t.integer "column03", default: 300 t.float "column44" t.boolean "column11" t.string "column99" end create_table "sample4", force: true do |t| t.string "column01", limit: 100 t.integer "column02", default: 200 t.float "column03", null: false end add_index "sample4", ["column01"], name: "index_sample4_on_column01", using: :btree add_index "sample4", ["column02", "column03"], name: "index_sample4_on_column02_and_column03", using: :btree add_index "sample4", ["column02"], name: "index_sample4_on_column02", unique: true, using: :btree add_index "sample4", ["column03"], name: "column03_index", using: :btree end
参考リファレンス
create_table
http://railsdoc.com/references/create_table
add_column
http://railsdoc.com/references/add_column
change_column
http://railsdoc.com/references/change_column
change_column_default
http://railsdoc.com/references/change_column_default
rename_column
http://railsdoc.com/references/rename_column
remove_column
http://railsdoc.com/references/remove_column
remove_columns
http://railsdoc.com/references/remove_columns
add_index
http://railsdoc.com/references/add_index
remove_index
http://railsdoc.com/references/remove_index
rename_index
http://railsdoc.com/references/rename_index