
在 FastAPI 專案中,我們通常使用 ORM (Object Relational Mapping) 來操作資料庫,這樣我們就可以用 Python 物件的方式來寫 SQL,而不需要寫原本的 SQL 語句。
Python 界最強大的 ORM 是 SQLAlchemy,但它有點複雜。於是 FastAPI 的作者開發了 SQLModel,它是 SQLAlchemy + Pydantic 的合體,專為現代 Python 打造。
1. 安裝
pip install sqlmodel
2. 定義模型
SQLModel 的特點是:同一個類別,既是 Pydantic Model (用於驗證),也是 SQLAlchemy Model (用於資料庫)。
from typing import Optional
from sqlmodel import Field, SQLModel, create_engine, Session
# 繼承 SQLModel, table=True 代表這是一個資料庫表格
class Hero(SQLModel, table=True):
id: Optional[int] = Field(default=None, primary_key=True)
name: str
secret_name: str
age: Optional[int] = None
# 建立 SQLite 資料庫連線
sqlite_file_name = "database.db"
sqlite_url = f"sqlite:///{sqlite_file_name}"
engine = create_engine(sqlite_url, echo=True) # echo=True 會印出 SQL 語句方便除錯
def create_db_and_tables():
SQLModel.metadata.create_all(engine)
3. 寫入資料 (Create)
def create_heroes():
hero_1 = Hero(name="Deadpool", secret_name="Wade Wilson")
hero_2 = Hero(name="Spider-Man", secret_name="Peter Parker")
# 使用 Session 管理交易 (Transaction)
with Session(engine) as session:
session.add(hero_1)
session.add(hero_2)
session.commit() # 提交變更
4. 讀取資料 (Read)
from sqlmodel import select
def select_heroes():
with Session(engine) as session:
# 寫起來就像 Python 語句
statement = select(Hero).where(Hero.name == "Deadpool")
results = session.exec(statement)
hero = results.first()
print(hero)
5. 整合 FastAPI
最棒的部分來了:依賴注入 (Dependency Injection)。我們可以讓 FastAPI 自動管理資料庫連線的開啟與關閉。
from fastapi import FastAPI, Depends
app = FastAPI()
# 定義依賴:取得 Session
def get_session():
with Session(engine) as session:
yield session
@app.post("/heroes/")
def create_hero(hero: Hero, session: Session = Depends(get_session)):
session.add(hero)
session.commit()
session.refresh(hero) # 獲取資料庫生成的新 ID
return hero
@app.get("/heroes/")
def read_heroes(session: Session = Depends(get_session)):
heroes = session.exec(select(Hero)).all()
return heroes
6. 總結
使用 SQLModel,我們不再需要分開定義 “Pydantic Schema” 和 “Database Model”,一個 Class 搞定全部。
這極大程度地簡化了程式碼,且完美保留了 Type Hints 的優勢。
下一章,也就是 Batch 8 的最後一章,我們將學習如何將寫好的 FastAPI 服務打包成 Docker 容器,準備部署到雲端!
延伸閱讀: