箱のプログラミング日記。

えんじにあ奮闘記

Index name 'index_hoge' on table 'hoge_fugas' already exists と言われた時

migrateしたら遭遇したエラーの対処法。

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

hoge_fugasテーブルのhogeカラムにインデックスを貼ろうとしたらすでに存在するよと言われている感じ。

とりあえず状況を確認してみると

bin/rake db:migrate:status
.
.
.
 up     20200318050946  Create hoges
down    20200326085429  Create hoge_fugas

一番最後の中間テーブルを作成するマイグレーションが実行されていない。

mysqlにログインしてどこまで進んでいるのか見てみる

bin/rails db
mysql> show columns from hoge_fugas;
+------------------+------------+------+-----+---------+----------------+
| Field            | Type       | Null | Key | Default | Extra          |
+------------------+------------+------+-----+---------+----------------+
| id               | bigint(20) | NO   | PRI | NULL    | auto_increment |
| hoge_id          | bigint(20) | NO   | MUL | NULL    |                |
| created_at       | datetime   | NO   |     | NULL    |                |
| updated_at       | datetime   | NO   |     | NULL    |                |
+------------------+------------+------+-----+---------+----------------+

テーブルの作成までは完了している模様。

(ちなみにここでshow tablesでテーブル一覧を表示してhoge_fugasを探しても良い)

次にインデックスが貼られているかどうか見てみる

mysql> show index from hoge_fugas;
+--------------------------+------------+----------------------------------------------------+--------------+------------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table                    | Non_unique | Key_name                                           | Seq_in_index | Column_name      | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+--------------------------+------------+----------------------------------------------------+--------------+------------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| hoge_fugas |          0 | PRIMARY                                            |            1 | id               | A         |           5 |     NULL | NULL   |      | BTREE      |         |               |
| hoge_fugas |          1 | index_hoge_fugas_on_hoge_id |            1 | hoge_id | A         |           5 |     NULL | NULL   |      | BTREE      |         |               |
+--------------------------+------------+----------------------------------------------------+--------------+------------------+-----------+-------------+----------+--------+------+------------+---------+---------------+

インデックスも貼られている模様。

うーんなぜエラーになったのかよくわからないが、、とりあえず今中途半端に出来上がってしまっているものを一つずつmysqlで直接リセットしていって、再度マイグレーションしなおしてみる

インデックスを削除

mysql> ALTER TABLE hoge_fugas DROP INDEX index_hoge_fugas_on_hoge_id;
Query OK, 0 rows affected, 2 warnings (0.02 sec)
Records: 0  Duplicates: 0  Warnings: 2

Query OKとなれば成功。

念の為確認

mysql> show index from hoge_fugas;
+--------------------------+------------+----------------------------------------------------+--------------+------------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table                    | Non_unique | Key_name                                           | Seq_in_index | Column_name      | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+--------------------------+------------+----------------------------------------------------+--------------+------------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| hoge_fugas |          0 | PRIMARY                                            |            1 | id               | A         |           5 |     NULL | NULL   |      | BTREE      |         |               |
+--------------------------+------------+----------------------------------------------------+--------------+------------------+-----------+-------------+----------+--------+------+------------+---------+---------------+

PRIMARYキーのみになっているのでOK。

ちなみに主キーもインデックス外した方が良いのかなとか一瞬変なことを考えたのだけど、エラーになったので要らなかった。

そしたら次のステップへ

テーブルを削除

インデックスを剥がせたらテーブルを削除する

mysql> drop table hoge_fugas;
Query OK, 0 rows affected (0.00 sec)

念の為確認

mysql> show index from hoge_fugas;
ERROR 1146 (42S02): Table 'sample_db.hoge_fugas' doesn't exist

ちゃんと消えている模様。

もう一度migrate

migrationのステータスとmysqlのテーブル状況を一致させることができて綺麗な状態になったので、再度migrateする

bin/rake db:migrate
== 20200326085429 CreateHogeFugas: migrating =====================
-- create_table(:hoge_fugas)
   -> 0.0166s
== 20200326085429 CreateHogeFugas: migrated (0.0166s) ============

成功した。

参考

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