Rails5のproductionでrake db:dropはできない、普通には


概要

Rails5から、productionモードでは、db:dropなどのDBを破壊する系のコマンド実行を防止する機能が追加された。

下記はproductionで rake db:drop する時の手順。


ar_internal_metadataテーブルのenvironmentをproductionにする

まずは、developmentやstagingなどの違う環境のDBをdumpして、productionのDBに入れたときなどに起こるエラーの対処法についてです。

productionでrake db:dropする方法のみ知りたい方は、次の項目へ進んで下さい

productionになっていないとこんなエラーが出る

$ RAILS_ENV=production bundle exec rake db:drop

rake aborted!
ActiveRecord::EnvironmentMismatchError: You are attempting to modify a database that was last run in `staging` environment.
You are running in `production` environment. If you are sure you want to continue, first set the environment using:

bin/rails db:environment:set RAILS_ENV=production


原因

このエラーは、ar_internal_metadata テーブルにセットされているenvironmentと、実行しようとしているコマンドで指定されたものが一致していない場合に出る。

developmentやstagingなどの違う環境のDBをdumpして、productionのDBに入れたときなどに起こる。

mysql> select * from ar_internal_metadata;

+-------------+-------------+---------------------+---------------------+
| key | value | created_at | updated_at |
+-------------+-------------+---------------------+---------------------+
| environment | development | 2017-03-28 05:54:51 | 2017-03-28 05:54:51 |
+-------------+-------------+---------------------+---------------------+
1 row in set (0.00 sec)


対処法

下記のコマンドで、ar_internal_metadata のenvironmentをproductionに更新する。

$ bundle exec rails db:environment:set RAILS_ENV=production


productionでdb破壊系の処理を実行するとエラーになる

こんなエラーが出る

$ RAILS_ENV=production bundle exec rake db:drop

rake aborted!
ActiveRecord::ProtectedEnvironmentError: You are attempting to run a destructive action against your 'production' database.
If you are sure you want to continue, run the same command with the environment variable:
DISABLE_DATABASE_ENVIRONMENT_CHECK=1


原因


参考


意図的にproduction environmentのDBを破壊したい場合は、エラーメッセージにも表示されている通り、

環境変数 DISABLE_DATABASE_ENVIRONMENT_CHECK=1指定してあげればOKです。

防止処理の対象となるtaskは下記の通りです。

db:drop

db:drop:all

db:purge

db:purge:all

db:purge:test

db:schema:load


Rails 5に入ったDB破壊系taskの防止処理について

Rails5では、DBを破壊する系のコマンドを防止する機能が追加されているようです。


対処法

参考記事の通り、環境変数に

DISABLE_DATABASE_ENVIRONMENT_CHECK=1

を付与すればよいので、下記のコマンドでdropできる。

$ RAILS_ENV=production DISABLE_DATABASE_ENVIRONMENT_CHECK=1 bundle exec rake db:drop

以上


参考

Rails 5に入ったDB破壊系taskの防止処理について

Rails5にてrails db:dropを行う方法

Rails5でDBに自動生成されるテーブル、"ar_internal_metadata" とは何なのか