HerokuでDATABASE_URLを変更しようとしたらCannot overwrite attachment values DATABASE_URLと言われる

Posted on
Heroku
thumbnail

はじめに

訳あってとあるHeroku上のRailsアプリで使っているDBをHeroku PostgresからGoogle Cloud SQLにしようと思ったのですが、DATABASE_URLを書き換えようとしたらCannot Overwrite Attachment Values DATABASE_URLと言われてしまいました。

$ heroku config:set DATABASE_URL="postgres://{Cloud SQLの接続情報}" -a xxxxx-xxxxx-xxxxx
Setting DATABASE_URL and restarting ⬢ xxxxx-xxxxx-xxxxx... !
 ▸    Cannot overwrite attachment values DATABASE_URL.

DATABASE_URLって上書きできないのかよ…というのが率直な感想。

対処法

  • いろいろと調べてみたところ、いったんHeroku postgresをdetachしてみると良いとあったので試してみた。

    $ heroku addons:detach DATABASE -a xxxxx-xxxxx-xxxxx
    Detaching DATABASE to postgresql-xxxxxx-xxxxxx from ⬢ xxxxx-xxxxx-xxxxx... !
    ▸    Cannot destroy last attachment to billing app for resource postgresql-xxxxxx-xxxxxx
    
  • やっぱりダメだった。

  • さらに調べるとHeroku postgresをdestroyすると良いとあったので試してみる。

  • と言いたいところだが、本番運用中のDBをアドオンから削除するというのは正直やりたくないものですよね。

  • 幸い今回はユーザーからの書き込みがないRailsアプリケーションでデータはなんとでもできるので思い切ってdestroyしてみました。

    $ heroku addons:destroy DATABASE -a xxxxx-xxxxx-xxxxx
    ▸    WARNING: Destructive Action
    ▸    This command will affect the app xxxxx-xxxxx-xxxxx
    ▸    To proceed, type xxxxx-xxxxx-xxxxx or re-run this command with --confirm xxxxx-xxxxx-xxxxx
    
    > xxxxx-xxxxx-xxxxx
    Destroying postgresql-xxxxxx-xxxxxx on ⬢ xxxxx-xxxxx-xxxxx... done
    
  • 削除できたっぽいので続いてDATABASE_URLをCloud SQLのものに書き換える。

    $ heroku config:set DATABASE_URL="postgres://{cloud sqlのurl}" -a xxxxx-xxxxx-xxxxx
    Setting DATABASE_URL and restarting ⬢ xxxxx-xxxxx-xxxxx... done, v124
    ▸    Release command executing: this config change will not be available until the command succeeds. Use `heroku releases:output` to view the log.
    DATABASE_URL: postgres://{cloud sqlのurl}
    
  • できたっぽい。

おわりに

  • Heroku Postgres add-onを利用している間はDATABASE_URL環境変数は上書きできない。
  • addons:detachもしくはaddons:destroyせずに本番環境が参照するデータベースを変更したい場合はどうするのが良いのか?という疑問。
  • DATABASE_URL以外の環境変数(仮にTMP_DATABASE_URLとしておく)を用意しておいて、database.ymlのproductionでTMP_DATABASE_URLを参照するようにしてやるのが良いかもしれない。
  • Heroku Postgresを使っているとdatabase.ymlのproductionに特に何も設定書かなくても勝手にDATABASE_URLを参照してくれたりするので上記のやり方が使えるのかはちょっと検証の必要がありそうな気がする。
    ActiveRecordがDATABASE_URLという環境変数があったら使うようにしているだけだった。

参考