YamAgent 資料關聯修復紀錄:ForeignKey、Cascade 刪除與 JSON Response
這篇紀錄的是我在開發 YamAgent
專案時,針對 Session 模組的資料表關聯與刪除邏輯進行修復與重構的過程。從 ForeignKey 錯誤、ORM relationship
的使用,到 RESTful API 回應行為,整個流程雖然繁瑣,但修完之後整個系統更乾淨、穩定。
🧩 問題背景
我希望在刪除某筆 Session
時,能同時清除與其關聯的:
- ChatHistory
- MemoryRecord
- TokenUsageRecord
但實際執行時出現了以下錯誤:
- PostgreSQL 拒絕刪除:
ForeignKeyViolation
- Alembic 找不到
sessions
table:NoReferencedTableError
- SQLAlchemy ORM 無法初始化:
relationship expects a class
- 前端收到錯誤:
Unexpected end of JSON input
🔧 解法摘要
1️⃣ 正確設計 ForeignKey(Cascade 刪除)
session_id = Column(UUID(as_uuid=True), ForeignKey("sessions.id", ondelete="CASCADE"))
2️⃣ 補上雙向 relationship
# 子 model
session = relationship("SessionRecord", back_populates="chat_history", passive_deletes=True)
# Session model
chat_history = relationship("ChatHistory", back_populates="session", cascade="all, delete-orphan")
3️⃣ 修正 class 名拼錯:"Session"
→ "SessionRecord"
SQLAlchemy 要的是 ORM class,不是 table name!
4️⃣ Alembic 重新產生 migration
- 確保
env.py
有 import 所有 model alembic revision --autogenerate
alembic upgrade head
5️⃣ 修正 REST API delete 回傳錯誤
原本這樣會報錯:
@router.delete(..., status_code=204)
return {"message": "刪除成功"} # ❌ 204 不能回傳 body
改為:
@router.delete(..., status_code=200)
return {"message": "刪除成功"} # ✅
✅ 最終成果
- 可以順利刪除 Session,且關聯資料會自動清除
- 不再出現外鍵錯誤
- 前端能正確收到 JSON response
- Alembic migration 與資料庫 schema 同步
🧠 心得
這次修復讓我更熟悉了 SQLAlchemy 的 cascade 機制與 Alembic 的 model 掃描邏輯。也再次體會到 RESTful 的 response 行為與狀態碼配對的嚴謹性。
雖然中間踩了一堆坑,但總算還是修好了 🎉