はじめに
RailsアプリをRenderにデプロイして運用していたのですが、無料で使っていたPostgreSQLの期限が切れてしまい、Renderから「データベースを削除しますよ」という通知が。
そこで、新しくPostgreSQLのインスタンスを作成して再デプロイを行ったところ、ビルドに失敗し、以下のエラーが発生しました。
PG::UndefinedTable: ERROR: relation “questions” does not exist
原因を調べた結果、最終的にビルドコマンドを rake db:setup に切り替えることで解決できたので、その流れをメモとして残します。
状況整理
- Render上で無料のPostgreSQLを使っていたが、期限切れで削除されることになった
- 新しいデータベースをRenderで作成
- アプリの環境変数
DATABASE_URLを新しいDBのURLに更新 - デプロイを再実行
-
render-build.shの中では、これまで通りbundle exec rake db:migrateを実行していた
エラーの原因
表示されたエラーは以下の通りです。
PG::UndefinedTable: ERROR: relation “questions” does not exist
これは、マイグレーションの途中で questions テーブルにカラムを追加しようとして失敗していることを示しています。
原因は、**「テーブルがまだないのに、カラムを追加しようとしていた」**ことでした。
新しいデータベースなので、当然テーブルはひとつも存在していません。
この状態で db:migrate を実行しても、変更対象のテーブルがないためエラーになってしまいます。これはデータベースを最初から構築する系のコマンドを使うべき状況でした。
解決方法:db:setup に変更する
デプロイスクリプト render-build.sh の中で実行していた bundle exec rake db:migrate を bundle exec rake db:setup に変更したところ、無事にデプロイが成功しました。
変更後の render-build.sh
#!/usr/bin/env bash
# exit on error
set -o errexit
bundle install
bundle exec rake assets:precompile
bundle exec rake assets:clean
bundle exec rake db:setup # ← ここを変更
db:setup を実行することで、テーブル作成・マイグレーション・seedデータの投入まで、すべて一発で実行してくれます。
⚠️ 注意点:データはすべて消えます
今回、データベースを新しく作り直したため、以前のDBにあったデータはすべて失われています。
- ユーザー情報も投稿データもゼロの状態になります。
- 外部サービスと紐づいていたデータもリセットされます。
- 必要であれば
db/seeds.rbで初期データを用意しておきましょう。大事なデータを扱っている場合は、Renderの有料プランでバックアップを有効にするか、手動でエクスポートして保管しておくことを強くおすすめします。
db:migrate と db:setup の違い
ざっくりと違いをまとめると、以下のようになります。
| コマンド | 用途 | 注意点 |
|---|---|---|
db:migrate |
既存のDBスキーマに変更を加える(マイグレーションを実行) | テーブルが既に存在していることが前提 |
db:setup |
DBの初期構築(DB作成+スキーマ読み込み+seed投入) | 新しい環境でDBを使い始めるときに便利 |
db:setup は内部的に db:create, db:schema:load, db:seed を実行しています。そのため、まっさらな状態からデータベースを立ち上げるのに最適です。
まとめ
- Renderで新しいデータベースに切り替えたら、
bundle exec rake db:setupを使うとスムーズ。 -
「relation does not exist」 エラーは、テーブルが存在しない状態で
db:migrateを実行したことが原因の可能性が高い。 - データベースを新規作成すると、中のデータはすべて消えるので、バックアップや初期データの準備を忘れずに!
同じようにRenderでデータベースの移行時にハマった方の助けになれば幸いです。