Flask × SQLAlchemy × Render(PostgreSQL)でタスク管理アプリを運用していたところ、
新しいカラム(due_date)を追加した直後に /tasks ページで f405 エラーが発生しました。
エラー内容は次の通りです。
sqlalchemy.exc.ProgrammingError: column worktasks.due_date does not exist
モデルには追加したはずなのに、DB には存在しない…。
そんな状況から原因を突き止めて解決するまでの流れをまとめます。
発生した問題
アプリ側では WorkTask モデルに due_date カラムを追加していました。
due_date = db.Column(db.Date)
しかし、Render の PostgreSQL には due_date カラムが存在していなかったため、
アプリが SELECT を実行した瞬間にエラーが発生しました。
原因:SQLAlchemy の create_all() は既存テーブルを更新しない
今回の原因はとてもシンプルで、
既存テーブルに新しいカラムが追加されていなかった
ということでした。
SQLAlchemy の create_all() は「テーブルが存在しない場合のみ作成」するため、
既存テーブルの構造変更(カラム追加・削除)は自動で行われません。
そのため、モデルにカラムを追加しても、
DB 側には反映されず、構造が古いまま残っていました。
解決方法:PostgreSQL に手動でカラムを追加する
Render の無料プランでは SQL Editor が使えないため、
psql で接続して手動で ALTER TABLE を実行しました。
1. psql で接続
Render の PostgreSQL → “Connections” → External Connection の URI を使用。
psql "postgres://xxxxxx"
2. テーブル構造を確認
\d worktasks
3. カラムを追加
ALTER TABLE worktasks ADD COLUMN due_date DATE;
4. 再度確認
\d worktasks
due_date が追加されていれば成功です。
その後:アプリ側でも正常に動作
カラム追加後、アプリを再デプロイすると /tasks ページのエラーは解消され、
期限付きタスクの追加・表示が正常に動作するようになりました。
学んだこと
今回のトラブルから得た学びは以下の通りです。
- SQLAlchemy の
create_all()は既存テーブルを更新しない - カラム追加・削除は手動で ALTER TABLE が必要
- Render の無料プランは SQL Editor が無いので psql で対応する
- モデル変更後は DB の構造を必ず確認する
- エラーが出たら「DB の構造が最新か?」をまず疑う
まとめ
今回の f405 エラーは、
「アプリのモデルは更新されているのに、DB のテーブル構造が古いままだった」
というのが原因でした。
SQLAlchemy を使う場合、
テーブル構造の変更は自動で反映されないため、
手動で ALTER TABLE を実行する必要があります。
同じように Render × Flask × PostgreSQL を使っている方の参考になれば幸いです。
