質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Docker

Dockerは、Docker社が開発したオープンソースのコンテナー管理ソフトウェアの1つです

Q&A

解決済

2回答

2770閲覧

dockerのdatastoreで正しく復元されているRailsアプリケーションで、Migration are pendingエラーが発生する場合の対処法

hrmths

総合スコア17

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Docker

Dockerは、Docker社が開発したオープンソースのコンテナー管理ソフトウェアの1つです

0グッド

1クリップ

投稿2017/02/19 02:49

前提

  • docker for MACで開発中
  • コンテナは、web(rails)、mysql、datastore(busybox)

起きている事象

  • dockerコンテナを全てstopして、再度起動docker-compose upすると、datastoreのデータからdbをリストアしてくれる。
  • コンテナが立ち上がった状態でlocalhostでアクセスしようとすると、Migrations are pending. To resolve this issue, run: bin/rake db:migrate RAILS_ENV=development というエラーが発生

そもそもなのですが、なぜMigration are pendingになっているのかわからずでして。。
もしかしたら以前、この質問でやったみたいに、schema.rb からリストアしたのが問題でしょうか?

試しにrails db:migrateをしてみると以下のようなエラーがでます。

root@xxxxxxxxxxx:/myapp# bin/rake db:migrate RAILS_ENV=development == 20160830225620 CreateUsers: migrating ====================================== -- create_table(:users) rake aborted! StandardError: An error has occurred, all later migrations canceled: Mysql2::Error: Table 'users' already exists: CREATE TABLE `users` (`id` int(11) auto_increment PRIMARY KEY, `name` varchar(255), `created_at` datetime NOT NULL, `updated_at` datetime NOT NULL) ENGINE=InnoDB ROW_FORMAT=DYNAMIC

これを見る限り、migrationファイルも最初から流すわけではなく、途中から実行されエラーになっているようです。(20160830225620 CreateUsersは後半のmigrationファイルという意味です)

このような場合、どのように対応するのがよいでしょうか?
20160830225620 CreateUsers このmigrationファイル以降で、実行しているテーブルやカラムを、一度削除した上で、rails db:migrateを実行するしかないでしょうか。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

こんにちは。

Docker (Dockerのdatastore)の問題というよりは、schema.rb を使ってテーブルを復元した状態で、さらに db:migrateをしようとしたことが問題かなと思います。

トラブル前は、hrmthsさんはrailsのgenerate model / migrationコマンドを使ってテーブルを作成されていたかと思います。

その場合は、20160830225620_create_users.rb というファイルが出来て、rake db:migrate を使ってDBに対してテーブルを作成、もしくは変更...という流れですよね。

rake db:migrate の時は、schema_migrations というテーブルが自動で作成されて、そこにmigrationの履歴用の値がセットされます。

Usersテーブルができた場合は、20160830225620 という値が入ります。
そのほかのテーブルに関しても、migrationのファイルに付いている日付の値が、schema_migrationsテーブルに登録されていきます。


ここまではご周知かと思います。

さて、トラブルでDBを空っぽの状態から再作成されたとのことですが...。

rake db:reset の際に、schema.rb を使ってのテーブルの復元だと、1つのファイルで一気にテーブルを作成しますので、schema_migrationsのテーブルには、0 という値だけがセットされます。

つまり、rake db:migrate を行なったときとほぼ同じ構造のテーブルは作成されるものの、schema_migrations (マイグレーションの記録)は 0 スタートになります。

この状態で、rake db:migrate をしようとすると、20160830225620_create_users.rb が読み込まれたときに、20160830225620 という値が入っていないため、Railsは「まだこのテーブルは作成されてないな」と判断して、creaate tableを実施しようとします。

ここで、Mysql2::Error: Table 'users' already exists で怒られてしまうのだと思います。

sqliteとかの簡単なDBに対して、rake db:reset -> rake db:migrate を実施すると、同じエラーが再現されるのではないでしょうか。


ひとまずなんとかしたい場合は、こんな方法もありです。

  1. 別な綺麗な環境で rake db:migrate して、ひとととおりテーブルを作成

(db:reset ではなくて、db:drop / db:cretae / db:migrate )
2. schema_migrations に記録されている値を問題のDB側にコピーしてあげる

多分これでその後のrake db:migrate はエラーにならないと思います。
また、新規のDBに対してテーブル作成(migration)をする際は、db:reset -> db:migrateは行わず、db:create -> db:migrate をすれば大丈夫だと思います。

このへんも参考までに:
http://d.hatena.ne.jp/yk5656/20140102/1388614850

投稿2017/02/20 12:10

編集2017/02/20 12:15
suama

総合スコア1997

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hrmths

2017/02/20 23:06

suamaさん、とてもわかりやすいご説明ありがとうございます。 `schema_migrations` で記録しているのですね。ということは、エラーが発生した以降のmigrationファイルの数字の部分を、`schema migrations` に追加したらクリアしそうですね(migration済みと扱われる)。
hrmths

2017/02/20 23:14

立て続けにすみません。一応エラーは発生しなくなったのですが、これってありなんですかね、、? >でもmigrationファイルがずれたというか、最初から流しても正しくDBができないような形になってしまいました。migrationファイルを一度全部消して、schema.rbを見ながら、正規化してつくりなおすというのはありなんでしょうか?
suama

2017/02/20 23:18

schema.rb (& rake db:load) だけを使い、rake db:migrateを使わないケースとしてはspecなどテスト用のDBをささっと作るときとか、新規にrailsでテーブルを作りながら管理するのではなくて、既存のテーブルを利用しつつrailsに置き換えて行くときなどかな、と思います。 一式すでに固まった構成がある場合はschema.rbに記載、version = 0で作成し、その後追加していく際はmigrationのファイルを追加していくとか。
suama

2017/02/20 23:22

入れ違いですみません。 > migrationファイルを一度全部消して、schema.rbを見ながら、正規化してつくりなおすというのはありなんでしょうか? 上記で添えたように、「すでにテーブルが一式あって別のフレームワークで動いていたシステムをrailsに置き換える」とか、開発段階ではとりあえずmigrationでガンガン作っていってある程度Fixしたら整理し直すことはたくさんあると思いますので、いろんなケースがあるのかなあと思います。 マイグレーションが面倒なので、別のgemを使ったりすることもありますし...。
hrmths

2017/02/20 23:23

>一式すでに固まった構成がある場合はschema.rbに記載、version = 0で作成し、その後追加していく際はmigrationのファイルを追加していくとか。 なるほどです!そういうことが可能なのですね。勉強になりました。ありがとうございます!
hrmths

2017/02/20 23:29

>上記で添えたように、「すでにテーブルが一式あって別のフレームワークで動いていたシステムをrailsに置き換える」とか、開発段階ではとりあえずmigrationでガンガン作っていってある程度Fixしたら整理し直すことはたくさんあると思いますので、いろんなケースがあるのかなあと思います。 そうなんですね。migration一度整理してみます。ありがとうございますmm
guest

0

20160830225620 CreateUsers このmigrationファイル以降で、実行しているテーブルやカラムを、一度削除した上で、rails db:migrateを実行するしかないでしょうか。

これをやり、解決しました。でもmigrationファイルがずれたというか、最初から流しても正しくDBができないような形になってしまいました。migrationファイルを一度全部消して、schema.rbを見ながら、正規化してつくりなおすというのはありなんでしょうか?

投稿2017/02/19 23:32

hrmths

総合スコア17

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問