LoginSignup
1
0

More than 3 years have passed since last update.

Redmineプラグインのマイグレーションを適用した環境でdb:setup, db:resetを実行してはいけない

Last updated at Posted at 2019-09-29

確認したバージョン: Redmine 4.0.4, 3.4.11(たぶん他のバージョンでも起きる)

  1. Redmineプラグインのマイグレーションを適用済みの環境で
  2. rails db:setuprails db:resetを実行してしまうと
  3. rails redmine:plugins:migrateを実行するとTable already existsといったエラーが出て失敗するようになる。1

問題を起こさない方法

  • 新しいDBにスキーマを適用したい場合にはrails db:migrate redmine:plugins:migrateを実行する
  • DBのスキーマを作り直したい場合にはrails db:migrate:reset redmine:plugins:migrateを実行する2

問題が起きたあとの修正方法

  • rails db:migrate:reset redmine:plugins:migrateでDBを作り直す
  • schema_migrationsテーブルをいじってプラグインのマイグレーションが適用されたことにする
  • プラグインのマイグレーションで追加されたテーブルなどを手動で消す

のどれかで直る。だいたい上のほうが簡単なはず。

原因

  • db:setupdb:resetdb/schema.rbをソースにしてスキーマとマイグレーションの適用状況を復元する。
    • db/schema.rbのスキーマ情報にはRedmine本体のほか、プラグインのマイグレーションの結果も保存されているので、プラグインが追加したテーブルなどは正しく復元される。
    • しかしマイグレーションの適用状況はRedmine本体のものしか保存されていないので、プラグインのマイグレーションの適用情報は失われる。
  • そのため、次にredmine:plugins:migrateを実行するとプラグインのマイグレーションが二重に適用されてしまう。
    • マイグレーションの中でテーブルやカラムを追加していた場合、同名のテーブルなどがすでに存在するため、エラーが起きてマイグレーションが失敗する。
  • 一方、db:migrate:resetdb:migrateでマイグレーションをひとつずつ実行していくので、schema_migrationsテーブルとスキーマの不整合が起きない。

用語メモ

  • db/schema.rb: DBのスキーマ情報を保存したファイル3
    • (↓以下2つは確認してないけどたぶん合ってるはず)
    • マイグレーションの実行が完了するたびに更新される。
    • 最後に実行が完了したマイグレーションのバージョンを保持している。
  • schema_migrationsテーブル: どのマイグレーションを適用したかを記録しておくためのテーブル。

コードリーディングメモ

再現コード

再現確認用のリポジトリを作った。pushするたびにGitHub Actionsで

  1. 再現用のプラグインを用意する
  2. Redmineのソースをダウンロードして展開する
  3. プラグインとdatabase.ymlをRedmineのディレクトリに配置する
  4. rails db:create db:migrate redmine:plugins:migrateを実行してからrails db:reset redmine:plugins:migrateを実行してエラーメッセージを確認する

という感じのことをやっていて、不具合が再現したらコミットのステータスが緑になる。


  1. プラグインのすべてのマイグレーションがロールバックせずに何度でも実行できるなら問題は起きないが、そういうケースはごくまれだと思う。 

  2. ActiveRecord::ProtectedEnvironmentErrorが発生したらRails 5に入ったDB破壊系taskの防止処理について | 日々雑記などを参照。 

  3. 設定によってはdb/schema.rbではなくdb/structure.sqlになる。 

1
0
1

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
1
0