FastAPI + SQLModel 从 0 搭到完整 CRUD

FastAPI + SQLModel 从 0 搭到完整 CRUD

1. 安装依赖

bash 复制代码
python -m venv venv && source venv/bin/activate  # 可选
pip install "fastapi[standard]" sqlmodel

2. 目录结构(单文件也 OK)

ba 复制代码
project
├── main.py
└── models.py

3. 定义模型 models.py

python 复制代码
from typing import Optional
from sqlmodel import SQLModel, Field

class Hero(SQLModel, table=True):
    id: Optional[int] = Field(default=None, primary_key=True)
    name: str
    age: Optional[int] = None

4. 完整 main.py(含库初始化 + CRUD)

python 复制代码
from fastapi import FastAPI, Depends, HTTPException
from sqlmodel import Session, create_engine, select
from models import Hero, SQLModel

DATABASE_URL = "sqlite:///./hero.db"
engine = create_engine(DATABASE_URL, echo=True)

# 启动时自动建表
def create_db_and_tables():
    SQLModel.metadata.create_all(engine)

def get_session():
    with Session(engine) as session:
        yield session

app = FastAPI()

@app.on_event("startup")
def on_startup():
    create_db_and_tables()

# 新增英雄
@app.post("/heroes/", response_model=Hero)
def create_hero(hero: Hero, db: Session = Depends(get_session)):
    db.add(hero)
    db.commit()
    db.refresh(hero)
    return hero

# 查询全部
@app.get("/heroes/", response_model=list[Hero])
def read_heroes(db: Session = Depends(get_session)):
    return db.exec(select(Hero)).all()

# 查询单个
@app.get("/heroes/{hero_id}", response_model=Hero)
def read_hero(hero_id: int, db: Session = Depends(get_session)):
    hero = db.get(Hero, hero_id)
    if not hero:
        raise HTTPException(status_code=404, detail="Hero not found")
    return hero

# 更新
@app.put("/heroes/{hero_id}", response_model=Hero)
def update_hero(hero_id: int, updated: Hero, db: Session = Depends(get_session)):
    hero = db.get(Hero, hero_id)
    if not hero:
        raise HTTPException(status_code=404, detail="Hero not found")
    for k, v in updated.dict(exclude_unset=True).items():
        setattr(hero, k, v)
    db.commit()
    db.refresh(hero)
    return hero

# 删除
@app.delete("/heroes/{hero_id}")
def delete_hero(hero_id: int, db: Session = Depends(get_session)):
    hero = db.get(Hero, hero_id)
    if not hero:
        raise HTTPException(status_code=404, detail="Hero not found")
    db.delete(hero)
    db.commit()
    return {"ok": True}

5. 启动 & 测试

bash 复制代码
fastapi dev main.py --reload
# 或用 uvicorn main:app --reload

浏览器打开 http://127.0.0.1:8000/docs 即可看到自动生成的 Swagger UI,点点鼠标就能完成增删改查

6. 想换 PostgreSQL?

bash 复制代码
把 DATABASE_URL 改成
postgresql://user:pwd@localhost:5432/dbname
并额外安装 pip install psycopg2-binary 即可,其余代码零改动