FastAPI + SQLModel 从 0 搭到完整 CRUD
FastAPI + SQLModel 从 0 搭到完整 CRUD
1. 安装依赖
python -m venv venv && source venv/bin/activate # 可选
pip install "fastapi[standard]" sqlmodel
2. 目录结构(单文件也 OK)
project
├── main.py
└── models.py
3. 定义模型 models.py
from typing import Optional
from sqlmodel import SQLModel, Fieldclass Hero(SQLModel, table=True):id: Optional[int] = Field(default=None, primary_key=True)name: strage: Optional[int] = None
4. 完整 main.py(含库初始化 + CRUD)
from fastapi import FastAPI, Depends, HTTPException
from sqlmodel import Session, create_engine, select
from models import Hero, SQLModelDATABASE_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 sessionapp = 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. 启动 & 测试
fastapi dev main.py --reload
# 或用 uvicorn main:app --reload
浏览器打开 http://127.0.0.1:8000/docs 即可看到自动生成的 Swagger UI,点点鼠标就能完成增删改查。
6. 想换 PostgreSQL?
把 DATABASE_URL 改成
postgresql://user:pwd@localhost:5432/dbname
并额外安装 pip install psycopg2-binary 即可,其余代码零改动