FastAPI筑基_Day14_SQLAlchemy数据库实战
FastAPIçåº_Day14_SQLAlchemyæ°æ®åºå®æ
鲨鱼辣é 2026-08-20 0 é 读12åéãFastAPIçåº-Day14ãSQLAlchemy ORMæ°æ®åºå®æï½ä»é¶æå»ºMySQLè¿æ¥ãæ°æ®è¡¨ãCRUDã项ç®è§£è¦ï¼æç»å·¥ç¨åï¼
䏿 ï¼FastAPIé¶åºç¡åç«¯å®æç³»å æ ç¾ï¼FastAPIãSQLAlchemyãMySQLãORMãæ°æ®åºCRUDãå端工ç¨å åç½®å¦ä¹ ï¼Day11 è·¯ç±åå±ä¸é¡¹ç®å·¥ç¨ç®å½æåãDay13 JWT卿令ç鴿宿
ä¸ãåè¨
å颿æç« èçæ°æ®å ¨é¨é½æ¯å ååæ°æ®ï¼æå¡ä¸é坿°æ®å ¨ä¸¢ï¼æ°¸è¿æ æ³è½å°ç产ãDay14 æ£å¼æ¥å ¥æ°æ®åºï¼
åç«¯é¡¹ç® 90% çä¸å¡é½æ¯å´ç»æ°æ®åº CRUD å±å¼ï¼è FastAPI 宿¹æ é çæ°æ®åºæ¹æ¡å°±æ¯ SQLAlchemy ORMãæ¬ç¯æç« æä»¬å䏿¬¡å®æ´çæ°æ®åºå®æï¼ä»é¶é ç½® MySQL è¿æ¥ãORM æ¨¡åæ å°èªå¨å»ºè¡¨ãSession ä¼è¯ç®¡çï¼å° Model / Schema / CRUD / Router æ ååå±åå±ï¼æç»äº§åºä¸ä¸ªå¯å¨å³è·ãæ¥å£å ¨éãæ°æ®è½åºç宿´ç¨æ·ç®¡çå端ã
Day14 ç®æ æ¸ åï¼
- â SQLAlchemy è¿æ¥ MySQL 宿´é ç½®
- â ORM æ¨¡åæ å°ãèªå¨å»ºè¡¨
- â æ°æ®åºä¼è¯ Session 管ç
- â æ ååå±ç»æï¼Model / Schema / CRUD / Router
- â 宿´ç¨æ·å¢å æ¹æ¥ CRUD
- â ç»åä¹å JWT ç»å½ãç»ä¸ååºãå ¨å±å¼å¸¸
å¦å®æ¬ç« ï¼ä½ ç项ç®å°±æ¯ä¸ä¸ªå®æ´ä¸çº¿çº§å端项ç®ï¼æ¬ç³»åçåºç¯ä¹æ£å¼æ¶å®ï¼
äºãORM æ¯ä»ä¹ï¼ä¸ºä»ä¹è¦ç¨ SQLAlchemyï¼
ORMï¼Object Relational Mappingï¼å¯¹è±¡å ³ç³»æ å°ï¼ï¼ç¨ Python ç±»ä»£æ¿ SQL è¯å¥ï¼æä½å¯¹è±¡å°±æ¯æä½æ°æ®åºã
æä¸ªæ¯æ¹ï¼æ²¡æ ORM æ¶ï¼ä½ æ¯æä½ä¸æ¬¡æ°æ®åºé½è¦è¶´å°çªå£æå SQLï¼åå¨å½å¤åäºå¤§å
èªå·±å¡«å¤è¯è¡¨æ ¼ï¼æäº ORMï¼ç¸å½äºé
äºä¸ä½åå£°ä¼ è¯ââä½ åªç®¡ç¨ Python æä½å¯¹è±¡ï¼db.add(user)ãdb.query(User)ï¼ï¼ç¿»è¯å®èªå¨æä½ çæä½ç¿»è¯æ SQL äº¤ç»æ°æ®åºæ§è¡ï¼åæç»æç¿»è¯å Python 对象ã
graph LR
PY[Python 对象æä½<br>db.add / db.query] --> ORM[SQLAlchemy ORM<br>对象å
³ç³»æ å°]
ORM --> SQL[èªå¨çæ SQL]
SQL --> DB[(MySQL æ°æ®åº)]
DB --> ORM
ORM --> PY
ä¼å¿ï¼
- ä¸ç¨æå夿 SQLï¼ä»£ç æ´ä¼é
- èªå¨é² SQL æ³¨å ¥ï¼åæ°å ¨é¨ç»å®ä¼ åï¼ä¸æ¼æ¥å符串ï¼
- éé 夿°æ®åºï¼MySQL/SQLite/PostgreSQLï¼æ ç¼åæ¢ï¼åªæ¹è¿æ¥ä¸²
- åæ®µçº¦æãç±»åãé»è®¤å¼ç»ä¸å¨æ¨¡åé管ç
ä¸ãå®è£ ä¾èµä¸ MySQL åå¤
pip install sqlalchemy pymysql "passlib[bcrypt]" "bcrypt==4.0.1"
说æï¼
pymysqlï¼MySQL 驱å¨ï¼è´è´£çæ£å MySQL å»ºç« TCP è¿æ¥sqlalchemyï¼ORM æ ¸å¿åºpasslib+bcryptï¼å¯ç åå¸å å¯ï¼Day13 忬¾ï¼ï¼æ°æ®åºç»ä¸åææå¯ç
MySQL åç½®åå¤ï¼
- æ¬å°å®è£ å¹¶å¯å¨ MySQL
- åå»ºæ°æ®åºï¼
CREATE DATABASE fastapi_db DEFAULT CHARACTER SET utf8mb4;
- åé¢
database.pyä¸çè´¦å·å¯ç ä¿®æ¹ä¸ºèªå·±çï¼æ¬æä¸ºæ¬å°å¦ä¹ ç¯å¢ä½¿ç¨root/123456ï¼ç产请å¡å¿ æ¢å¼ºå¯ç ï¼
åãä¼ä¸çº§æ åå屿¶æï¼éç¹ï¼
æä»¬å°é¡¹ç®å½»åºè§£è¦ï¼è¿æ¯å¤§å FastAPI 项ç®çæ åç»æï¼
| å± | èè´£ | ç¦æ¢äºé¡¹ |
|---|---|---|
| models | æ°æ®åºå®ä½æ¨¡åï¼ä¸ä¸ªç±» = ä¸å¼ 表 | åä¸å¡é»è¾ |
| schemas | Pydantic 请æ±/ååºæ¨¡åï¼åæ°æ ¡éªãåºåå | ç¢°æ°æ®åº |
| crud | æ°æ®åºæä½é»è¾ï¼å¢å æ¹æ¥å ¨å¨è¿ | 碰 HTTPãç¢°åæ°æ ¡éª |
| routers | æ¥å£è·¯ç±å±ï¼åªè´è´£æ¥æ¶åæ°ãè°ç¨ CRUDãè¿åååº | ç´æ¥å SQL |
ä¸å¥è¯ï¼è·¯ç±ä¸ç¢°æ°æ®åºãCRUD ä¸ååæ°æ ¡éªã模ååå¸å ¶èã
请æ±ç宿´æµè½¬ï¼
graph TD
Client[客æ·ç«¯è¯·æ±] --> Router[routers è·¯ç±å±]
Router -. Pydantic èªå¨æ ¡éªåæ° .-> Schema[schemas æ ¡éªå±]
Router --> CRUD[crud æ°æ®æä½å±]
CRUD --> Model[models 模åå±]
Model --> DB[(MySQL)]
CRUD --> Router
Router --> Client
äºã宿´é¡¹ç®ç®å½
fastapi_project/
âââ main.py # 项ç®å
¥å£
âââ database.py # æ°æ®åºè¿æ¥é
ç½®
âââ requirements.txt # ä¾èµæ¸
å
âââ models/ # æ°æ®åºè¡¨æ¨¡å
â âââ user.py
âââ schemas/ # æ°æ®æ ¡éªæ¨¡å
â âââ user.py
âââ crud/ # æ°æ®åºæä½
â âââ user.py
âââ routers/ # æ¥å£è·¯ç±
â âââ user.py
âââ common/ # å
Œ
±å·¥å
·
âââ response.py
å ãåæ¥æ ¸å¿ä»£ç å®ç°
çæ¬æéï¼ç½ä¸å¾å¤èæç¨ç¨
from sqlalchemy.ext.declarative import declarative_baseãsessionmaker(autocommit=False)ãPydantic çorm_mode = Trueãè¿äºå¨ SQLAlchemy 2.x / Pydantic v2 ä¸å·²ç§»é¤æåºå¼ï¼ç´æ¥æä¼æ¥éãæ¬ç« ä»£ç å ¨é¨ææ°çåæ³ç¼åï¼å¯ç´æ¥è¿è¡ã
1. database.py æ°æ®åºå ¨å±é ç½®
from sqlalchemy import create_engine
from sqlalchemy.orm import declarative_base, sessionmaker
# æ°æ®åºè¿æ¥å°åï¼è¯·ä¿®æ¹ä¸ºèªå·±çè´¦å·å¯ç
SQLALCHEMY_DATABASE_URL = "mysql+pymysql://root:123456@localhost:3306/fastapi_db?charset=utf8mb4"
# åå»ºå¼æï¼è¿æ¥æ± ï¼
engine = create_engine(
SQLALCHEMY_DATABASE_URL,
pool_pre_ping=True, # 使ç¨åå
ping ä¸ä¸ï¼é¿å
使ç¨å°è¶
æ¶æå¼çåºè¿æ¥
pool_recycle=3600, # è¿æ¥æ¯å°æ¶åæ¶é建ï¼é²æ¢æ°æ®åºä¸»å¨æå¼
)
# ä¼è¯å·¥åï¼æ¯æ¬¡è¯·æ±éè¿å®å建ä¸ä¸ªç¬ç« Session
SessionLocal = sessionmaker(autoflush=False, bind=engine)
# ææ ORM 模åçåºç±»
Base = declarative_base()
# FastAPI ä¾èµæ³¨å
¥ï¼æ¯ä¸ªè¯·æ±æ¿å°ç¬ç«ä¼è¯ï¼è¯·æ±ç»æèªå¨å
³é
def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()
è¿æ¥ä¸²æ ¼å¼ï¼mysql+pymysql://è´¦å·:å¯ç @主æº:端å£/æ°æ®åºå?charset=utf8mb4ãget_db æ¯ Day12 ä¾èµæ³¨å
¥ç宿åºç¨ï¼ç¨ yield æä¼è¯äº¤ç»æ¥å£ï¼è¯·æ±ç»æ finally ä¿è¯å
³éï¼æ°¸ä¸æ³æ¼è¿æ¥ã
2. models/user.py æ°æ®åºè¡¨æ¨¡å
from sqlalchemy import Column, Integer, String, Boolean
from database import Base
class User(Base):
__tablename__ = "user"
id = Column(Integer, primary_key=True, index=True, autoincrement=True)
username = Column(String(50), unique=True, nullable=False, index=True)
password = Column(String(128), nullable=False)
email = Column(String(100), nullable=True)
is_active = Column(Boolean, default=True)
ä¸ä¸ªç±» = ä¸å¼ 表ï¼ä¸ä¸ª Column = ä¸åãunique å¯ä¸çº¦æãnullable é空约æãindex å ç´¢å¼ãdefault é»è®¤å¼ï¼å
¨é¨å¨æ¨¡åé声æã
3. schemas/user.py 请æ±ååºæ¨¡å
from typing import Optional
from pydantic import BaseModel, ConfigDict, Field
# åå»ºç¨æ·ï¼è¯·æ±ä½æ ¡éª
class UserCreate(BaseModel):
username: str = Field(min_length=2, max_length=20)
password: str = Field(min_length=6, max_length=32)
email: Optional[str] = None
# æ´æ°ç¨æ·ï¼ææå段å¯éï¼ä¼ åªä¸ªæ¹åªä¸ª
class UserUpdate(BaseModel):
password: Optional[str] = Field(default=None, min_length=6, max_length=32)
email: Optional[str] = None
is_active: Optional[bool] = None
# ç¨æ·ä¿¡æ¯è¿åï¼ä¸å«å¯ç åæ®µ
class UserInfo(BaseModel):
id: int
username: str
email: Optional[str]
is_active: bool
# SQLAlchemy 2.x + Pydantic v2 åæ³ï¼çä»·äºæ§ç orm_mode = True
model_config = ConfigDict(from_attributes=True)
注æ UserInfo éæ²¡æ password åæ®µï¼æ°æ®åºå¯¹è±¡è½¬ååºæ¶å¯ç èªå¨è¢«è¿æ»¤ï¼ç»ä¸æææ»æå¯ç åç»å端ã
4. crud/user.py æ°æ®åºCRUDé»è¾
from passlib.context import CryptContext
from sqlalchemy.orm import Session
from models.user import User
from schemas.user import UserCreate, UserUpdate
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
# å¯ç å å¯
def get_hash_pwd(password: str):
return pwd_context.hash(password)
# åå»ºç¨æ·
def create_user(db: Session, user: UserCreate):
db_user = User(
username=user.username,
password=get_hash_pwd(user.password),
email=user.email
)
db.add(db_user) # å å
¥ä¼è¯
db.commit() # æäº¤äºå¡ï¼çæ£ååº
db.refresh(db_user) # å·æ°æ¿å°èªå¢ id çæ°æ®åºåå¡«åæ®µ
return db_user
# æ ¹æ®ç¨æ·åæ¥è¯¢ç¨æ·
def get_user_by_name(db: Session, username: str):
return db.query(User).filter(User.username == username).first()
# æ ¹æ®IDæ¥è¯¢ç¨æ·
def get_user_by_id(db: Session, user_id: int):
return db.query(User).filter(User.id == user_id).first()
# è·åç¨æ·å表ï¼å页ï¼
def get_user_list(db: Session, page: int = 1, size: int = 10):
offset = (page - 1) * size
return db.query(User).offset(offset).limit(size).all()
# æ´æ°ç¨æ·ï¼åªæ´æ°è¯·æ±éå®é
æºå¸¦çåæ®µ
def update_user(db: Session, user_id: int, user: UserUpdate):
db_user = get_user_by_id(db, user_id)
if not db_user:
return None
data = user.model_dump(exclude_unset=True)
if "password" in data:
data["password"] = get_hash_pwd(data["password"])
for key, value in data.items():
setattr(db_user, key, value)
db.commit()
db.refresh(db_user)
return db_user
# å é¤ç¨æ·
def delete_user(db: Session, user_id: int) -> bool:
db_user = get_user_by_id(db, user_id)
if not db_user:
return False
db.delete(db_user)
db.commit()
return True
CRUD å±åªè®¤ Session 忍¡åï¼å®å
¨ä¸ç¥é HTTP çåå¨ï¼æ¢å°å½ä»¤è¡èæ¬ã宿¶ä»»å¡éä¹è½ç´æ¥å¤ç¨ã
5. routers/user.py æ¥å£è·¯ç±å±
from fastapi import APIRouter, Depends, Query
from sqlalchemy.orm import Session
from database import get_db
from schemas.user import UserCreate, UserInfo, UserUpdate
from crud import user as user_crud
from common.response import success_response, fail_response
router = APIRouter(prefix="/user", tags=["ç¨æ·æ°æ®åºæ¨¡å"])
# åå»ºç¨æ·
@router.post("/add", summary="æ°å¢ç¨æ·")
def add_user(user: UserCreate, db: Session = Depends(get_db)):
if user_crud.get_user_by_name(db, user.username):
return fail_response(msg="ç¨æ·åå·²åå¨")
res = user_crud.create_user(db, user)
return success_response(data=res.id, msg="ç¨æ·å建æå")
# æ ¹æ®ç¨æ·åæ¥è¯¢
@router.get("/name", summary="æ ¹æ®ç¨æ·åæ¥è¯¢")
def get_user(name: str, db: Session = Depends(get_db)):
res = user_crud.get_user_by_name(db, name)
if not res:
return fail_response(code=404, msg="ç¨æ·ä¸åå¨")
return success_response(data=UserInfo.model_validate(res))
# ç¨æ·å表å页
@router.get("/list", summary="ç¨æ·å表å页")
def user_list(
page: int = Query(1, ge=1),
size: int = Query(10, ge=1, le=100),
db: Session = Depends(get_db)
):
data = user_crud.get_user_list(db, page, size)
return success_response(data=[UserInfo.model_validate(u) for u in data])
# æ ¹æ®IDæ´æ°ç¨æ·
@router.put("/{user_id}", summary="æ´æ°ç¨æ·")
def update_user(user_id: int, user: UserUpdate, db: Session = Depends(get_db)):
res = user_crud.update_user(db, user_id, user)
if not res:
return fail_response(code=404, msg="ç¨æ·ä¸åå¨")
return success_response(data=UserInfo.model_validate(res), msg="æ´æ°æå")
# æ ¹æ®IDå é¤ç¨æ·
@router.delete("/{user_id}", summary="å é¤ç¨æ·")
def delete_user(user_id: int, db: Session = Depends(get_db)):
ok = user_crud.delete_user(db, user_id)
if not ok:
return fail_response(code=404, msg="ç¨æ·ä¸åå¨")
return success_response(msg="å 餿å")
è·¯ç±å±å
¨ç¨æ²¡æä¸è¡ SQLï¼Depends(get_db) 注å
¥ä¼è¯ â è° CRUD â å¥ç»ä¸ååºï¼ä¸ä»¶äºèå·²ã
6. common/response.py ç»ä¸ååº
from typing import Any
from fastapi.encoders import jsonable_encoder
from fastapi.responses import JSONResponse
def success_response(data: Any = None, msg: str = "è¯·æ±æå") -> JSONResponse:
return JSONResponse(status_code=200, content={"code": 200, "msg": msg, "data": jsonable_encoder(data)})
def fail_response(code: int = 400, msg: str = "请æ±å¤±è´¥", data: Any = None) -> JSONResponse:
return JSONResponse(status_code=200, content={"code": code, "msg": msg, "data": jsonable_encoder(data)})
jsonable_encoder è´è´£æ Pydantic 模åç对象转æå¯ JSON åºååçç»æï¼Day10 çèæåã
7. main.py ä¸»å ¥å£ & èªå¨å»ºè¡¨
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from database import engine, Base
from models.user import User # noqa: F401 建表åå¿
é¡»å
导å
¥æ¨¡åå®ææ³¨å
from routers.user import router as user_router
# èªå¨åå»ºæ°æ®è¡¨ï¼è¡¨ä¸å卿¶æå建ï¼
Base.metadata.create_all(bind=engine)
app = FastAPI(title="Day14 SQLAlchemyæ°æ®åºå®æ")
# è·¨å
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# 注åè·¯ç±
app.include_router(user_router)
@app.get("/")
def root():
return {"msg": "æ°æ®åºé¡¹ç®å¯å¨æåï¼è®¿é® /docs è°è¯æ¥å£"}
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=8000)
Base.metadata.create_all(bind=engine) 伿«æææç»§æ¿ Base çæ¨¡åï¼å¯å¨æ¶èªå¨å»ºè¡¨ï¼æ éæå建表 SQLãæ³¨æå¿
é¡»å
导å
¥æ¨¡å模åï¼æ¨¡å注åå° Base åæä¼è¢«å»ºè¡¨æ«å°ã
ä¸ãå¯å¨é¡¹ç®ï¼å ¨æµç¨å®æµ CRUD
å¯å¨é¡¹ç®ï¼
python main.py
1. 确认èªå¨å»ºè¡¨
æå¼ MySQL 客æ·ç«¯æ¥çï¼user 表已ç»èªå¨å建ï¼
mysql> SHOW TABLES;
+----------------------+
| Tables_in_fastapi_db |
+----------------------+
| user |
+----------------------+
2. Swagger ææ¡£ä¸è§
è®¿é® /docsï¼äºä¸ªç¨æ·æ¥å£æ´é½æå¨ãç¨æ·æ°æ®åºæ¨¡åãä¸ï¼
3. å¢ï¼æ°å¢ä¸¤ä¸ªç¨æ· + é夿°å¢æ¦æª
curl -X POST http://localhost:8000/user/add -H "Content-Type: application/json" \
-d '{"username":"zhangsan","password":"123456","email":"zhangsan@example.com"}'
{"code":200,"msg":"ç¨æ·å建æå","data":1}
curl -X POST http://localhost:8000/user/add -H "Content-Type: application/json" \
-d '{"username":"lisi","password":"abc123456"}'
{"code":200,"msg":"ç¨æ·å建æå","data":2}
é夿°å¢ zhangsanï¼è¢«è·¯ç±å±æ¥éæ¦æªï¼
{"code":400,"msg":"ç¨æ·åå·²åå¨","data":null}
4. æ¥ï¼æç¨æ·åæ¥è¯¢ + å表å页
curl "http://localhost:8000/user/name?name=zhangsan"
{"code":200,"msg":"è¯·æ±æå","data":{"id":1,"username":"zhangsan","email":"zhangsan@example.com","is_active":true}}
è¿åçæ¯ UserInfo ç»æï¼åªæ idãusernameãemailãis_activeï¼å¯ç åæ®µè¢«èªå¨è¿æ»¤ãæ¥è¯¢ä¸åå¨çç¨æ·ï¼
{"code":404,"msg":"ç¨æ·ä¸åå¨","data":null}
å页å表ï¼
curl "http://localhost:8000/user/list?page=1&size=10"
{"code":200,"msg":"è¯·æ±æå","data":[{"id":1,"username":"zhangsan","email":"zhangsan@example.com","is_active":true},{"id":2,"username":"lisi","email":null,"is_active":true}]}
5. æ¹ï¼æ´æ°ç¨æ·é®ç®±
curl -X PUT http://localhost:8000/user/1 -H "Content-Type: application/json" \
-d '{"email":"zhangsan_new@example.com"}'
{"code":200,"msg":"æ´æ°æå","data":{"id":1,"username":"zhangsan","email":"zhangsan_new@example.com","is_active":true}}
UserUpdate ææå段å¯éï¼ä¼ åªä¸ªæ¹åªä¸ªï¼ä¸ä¼ çåæ®µåæ ·ä¿çã
6. å ï¼å é¤ç¨æ·å¹¶ç¡®è®¤
curl -X DELETE http://localhost:8000/user/2
{"code":200,"msg":"å 餿å","data":null}
å é¤å忥 lisiï¼
{"code":404,"msg":"ç¨æ·ä¸åå¨","data":null}
7. åæ°æ ¡éªç §æ§çæ
å¯ç 太çï¼Pydantic ç´æ¥ 422 æ¦ä¸ï¼è¯·æ±æ ¹æ¬è¿ä¸å°æ°æ®åºå±ï¼
curl -X POST http://localhost:8000/user/add -H "Content-Type: application/json" \
-d '{"username":"wangwu","password":"123"}'
{"detail":[{"type":"string_too_short","loc":["body","password"],"msg":"String should have at least 6 characters","input":"123","ctx":{"min_length":6}}]}
8. å¨ Swagger éå¨çº¿æ°å¢ä¸ä¸ªç¨æ·
å¨ /docs éå±å¼ POST /user/addï¼ç¹ Try it out å¡«å
¥è¯·æ±ä½æ§è¡ï¼ååº code 200ï¼data è¿åæ°ç¨æ· idï¼
9. æåå» MySQL é亲ç¼ç¡®è®¤
mysql> SELECT id, username, LEFT(password, 13) AS pwd_prefix, email FROM user;
+----+----------+---------------+---------------------------+
| id | username | pwd_prefix | email |
+----+----------+---------------+---------------------------+
| 1 | zhangsan | $2b$12$ukg1Jt | zhangsan_new@example.com |
| 3 | wangwu | $2b$12$QftetQ | wangwu@example.com |
+----+----------+---------------+---------------------------+
æ°æ®ççè½å¨ MySQL éäºï¼é坿塿°æ®ä¾ç¶å¨ï¼å¯ç ååçæ¯ $2b$12$... å¼å¤´ç bcrypt åå¸ï¼ä¸æ¯ææãè³æ¤ CRUD å
¨é¾è·¯éç¯ã
å «ãç»åä¹åç« èï¼JWT é´æä¸å ¨å±å¼å¸¸ï¼éå¦ï¼
ç»ä¸ååºæ¬ç« å·²ç»ç¨ä¸ï¼JWT åå ¨å±å¼å¸¸å¨ Day13ãDay10 é½å·²åå¥½ï¼æ¥å ¥åªéåå ä¸è¡ï¼
æ JWT é´æï¼æ Day13 ç get_current_user åæ ·æå° common/auth.pyï¼ç¶åç»è·¯ç±å ä¸ä¸ª dependenciesï¼
from fastapi import Depends
from common.auth import get_current_user
# 该模åä¸æææ¥å£é½å¿
é¡»ç»å½åæè½è®¿é®
router = APIRouter(prefix="/user", tags=["ç¨æ·æ°æ®åºæ¨¡å"],
dependencies=[Depends(get_current_user)])
æå
¨å±å¼å¸¸ï¼æ Day10 ç两个 @app.exception_handler 注åå° main.pyï¼æ°æ®åºæ¥éãåæ°æ¥éç»ç»è¢«ç»ä¸ååºæ ¼å¼å
åºãå
·ä½å®ç°åç Day10 / Day13ï¼æ¬ç« ä¸éå¤è´´ä»£ç ã
ä¹ãæ ¸å¿ç¥è¯ç¹æ»ç»ï¼é¢è¯å¿ èï¼
| æ¦å¿µ | ä¸å¥è¯è¯´æ |
|---|---|
| Engine | æ°æ®åºè¿æ¥å¼æï¼å ¨å±å¯ä¸ï¼ç®¡çè¿æ¥æ± |
| Session | æ°æ®åºä¼è¯ï¼æ¯æ¬¡è¯·æ±ç¬ç«ä¼è¯ã请æ±ç»æèªå¨å ³é |
| Base 模å | æææ°æ®åºè¡¨çç¶ç±»ï¼create_all èªå¨å»ºè¡¨ |
| å屿¶æ | è·¯ç±ã模åãæ ¡éªãCRUD å®å ¨å离ï¼åå¸å ¶è |
| from_attributes | æ°æ®åº ORM 对象èªå¨è½¬ Pydantic 模åè¿ååç«¯ï¼æ§çå« orm_mode=Trueï¼ |
| add/commit/refresh | å å ¥ä¼è¯ â æäº¤äºå¡ â å·æ°æ¿æ°æ®åºåå¡«åæ®µï¼ååºä¸æ¥æ² |
åãæ¬ç³»å宿´æ¶å®æ»ç»ï¼Day1ï½Day14ï¼
å°æ¤ï¼FastAPI é¶åºç¡çåºç³»å宿´å®ç»ï¼ä½ ä»é¶ææ¡äºï¼
- Python 弿¥æ ¸å¿ãaiohttp é«å¹¶å
- å·¥ç¨æ¥å¿ãå½ä»¤è¡åæ°ã代ç è§è
- Pydantic å ¨èªå¨åæ°æ ¡éª
- GET/POSTãä¸å¤§ä¼ åãé«çº§åæ°æ ¡éª
- è·¨åãéææä»¶ãå ¨å±å¼å¸¸ãç»ä¸ååº
- è·¯ç±åå±ã模åå大åé¡¹ç®æ¶æ
- Depends ä¾èµæ³¨å ¥ãæ¥å£æéæ§å¶
- JWT æ ç¶æç»å½é´æä½ç³»
- SQLAlchemy ORM æ°æ®åº CRUD
å·²å®å ¨å ·å¤ç¬ç«å¼åä¼ä¸çº§åå端å离项ç®çè½åï¼
åä¸ãåç»è¿é¶é¢å
åç»è¿é¶ç³»åï¼FastAPI 宿´åå端åç¦»å®æé¡¹ç®ãRedis ç¼åã宿¶ä»»å¡ãæ¥å¿æä¹ åãDocker é¨ç½²ãçº¿ä¸æå¡å¨ä¸çº¿ãæä»¬è¿é¶ç¯è§ï¼
Aitishiku.com