LoginSignup
32
19

More than 5 years have passed since last update.

rails generate migrationしてエラーが出たときの対処法

Last updated at Posted at 2016-07-22

結構migration周りでエラーを起こすことが多くその度に調べていたので、メモ代わりに置いていこうかなと思っています。

Mysqlにログインする

以下のコマンドが基本です。

mysql -u ユーザー名 -D データベース名 -p

-u オプションでは MySQL に接続するユーザー名を指定します。
-D オプションでは接続先のデータベース名を指定します。
-p オプションはパスワードを送信する場合に指定します。

Mysql2::Error: Table 'hoges' already exists

既にそのtable名が存在しているのにmigrationをかけようとするとこのエラーが出ます。
「いやでもそんな記憶ないなー」という時は、mysqlにログインしてtableがあるのか確認します。
全てを見たい時は

show tables;

で指定したtableが見たい時は

show columns from hoges;

tableが存在しない時はerrorになるので一応存在しているかは確認できますw
もし、既存に存在していた場合は、作成したtable名を変更しましょう。

Index name 'index_hoge' on table 'homes' already exists

同じ名前のindex名のものがありますよというエラーです。
tableと同時にindexも貼っていてこのエラーになると結構厄介。

とりあえずmigrationがどこまで進んだのかを確認します。なのでmysqlにログイン。以下コマンドを打ちます

mysql> select * from schema_migrations;

そうすると

20150515072233
20150515072234
20150515102233

見たいのが出てきます。

ここでschema_migrationsについて少し触れておきます。


schema_migrationsとは
どのマイグレーションスクリプトまで実行済みなのかを記録するためのテーブルです。

で上記の数字の羅列の数字はどこから来たのかというと

rails generate migration hoges

した時に

db/migrate/20150515102233_create_hoges.rb

とできると思いますが、この時に付いている数字です。
なので今回で言うと2015/05/15にmigrateして作成されたファイルまで読み込んでますよーということになります。


話を戻します。なので、20150515102233以降は読み込まれていないということになります。
僕が作成したのは20160721044829だったので読み込まれていないことがわかります。

次にtableができているのかを以下のコマンドで確認します。

show columns from hoges;

エラーが出なければ、存在しています。

次にindexが貼られているかを確認します

show index from hoges;

これで見れます。存在していれば下のように出てきます。
スクリーンショット 2016-07-22 21.31.08.png

ここでエラーが出た時のカラムを見てindexが貼られているかを確認します。

貼られていなかった時は・・・対処方法は2つ。
① MySQLで書き換える
② 消去して、もう一度行う

① MySQLで書き換える
更新されていないindexをMySQLで直接書き込み、schema_migrationsにファイルをinsertしてあたかも処理したようにするという方法です。

ALTER TABLE テーブル名 ADD INDEX インデックス名(カラム名);

テーブル名がhogesのときは以下のようにすとindexを追加できます。

ALTER TABLE hoges ADD INDEX index_hoges_on_updated_at(updated_at);

そのあとにschema_migrationsをinsertします

INSERT INTO schema_migrations (version) VALUES(20160721044829);

そして、最後にエラー起こった

db/migrate/20160721044829_create_hoges.rb

のエラーが出た部分を修正して終了です。

② 消去して、もう一度行う
処理された過程を逆に辿ります。

まず、indexを消去します。

ALTER TABLE テーブル名 DROP INDEX インデックス名;

というルールなので

ALTER TABLE hoges DROP INDEX index_hoges_on_updated_at;

でindexを消去します。
そのあとにtableを消去します。

drop table hoges;

で、最後にmigrationして終了です。
ただこの場合、自分以外のmigrationファイルがある場合、それらも逆の手順を踏まないとエラーになるので①がオススメ。

自分用メモとしては長くなったが、これで今後何が起きてもmigrationにかんしては問題なさそうかな。

32
19
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
32
19