在FastAPI中使用类实现查询和业务逻辑
在FastAPI中,通过类来组织查询和业务逻辑可以使代码更加模块化、可维护。以下是几种常见的方式:
1. 服务类(Service Layer)模式
创建服务类
# services/user_service.py
from typing importList
from models import User
from schemas import UserCreate, UserUpdate
classUserService:
def__init__(self, db):
self.db = db
defget_user(self, user_id: int) -> User:
returnself.db.query(User).filter(User.id == user_id).first()
defget_users(self, skip: int = 0, limit: int = 100) -> List[User]:
returnself.db.query(User).offset(skip).limit(limit).all()
defcreate_user(self, user: UserCreate) -> User:
db_user = User(**user.dict())
self.db.add(db_user)
self.db.commit()
self.db.refresh(db_user)
return db_user
defupdate_user(self, user_id: int, user: UserUpdate) -> User:
db_user = self.get_user(user_id)
if db_user:
update_data = user.dict(exclude_unset=True)
for key, value in update_data.items():
setattr(db_user, key, value)
self.db.commit()
self.db.refresh(db_user)
return db_user
defdelete_user(self, user_id: int) -> bool:
db_user = self.get_user(user_id)
if db_user:
self.db.delete(db_user)
self.db.commit()
returnTrue
return False
在路由中使用服务类
# api/users.py
from fastapi import APIRouter, Depends
from sqlalchemy.orm import Session
from services.user_service import UserService
from schemas import UserCreate, UserUpdate, User
from database import get_db
router = APIRouter()
@router.get("/users/{user_id}", response_model=User)
defread_user(user_id: int, db: Session = Depends(get_db)):
user_service = UserService(db)
return user_service.get_user(user_id)
@router.post("/users/", response_model=User)
defcreate_user(user: UserCreate, db: Session = Depends(get_db)):
user_service = UserService(db)
return user_service.create_user(user)
# 其他路由...
2. 仓库模式(Repository Pattern)
创建基础仓库类
# repositories/base.py
from typing import TypeVar, Generic, List
from sqlalchemy.orm import Session
ModelType = TypeVar("ModelType")
classBaseRepository(Generic[ModelType]):
def__init__(self, model: ModelType, db: Session):
self.model = model
self.db = db
defget(self, id: int) -> ModelType:
returnself.db.query(self.model).filter(self.model.id == id).first()
defget_all(self, skip: int = 0, limit: int = 100) -> List[ModelType]:
returnself.db.query(self.model).offset(skip).limit(limit).all()
defcreate(self, obj_in):
db_obj = self.model(**obj_in.dict())
self.db.add(db_obj)
self.db.commit()
self.db.refresh(db_obj)
return db_obj
defupdate(self, id: int, obj_in):
db_obj = self.get(id)
if db_obj:
update_data = obj_in.dict(exclude_unset=True)
for key, value in update_data.items():
setattr(db_obj, key, value)
self.db.commit()
self.db.refresh(db_obj)
return db_obj
defdelete(self, id: int) -> bool:
db_obj = self.get(id)
if db_obj:
self.db.delete(db_obj)
self.db.commit()
returnTrue
return False
创建特定模型仓库
# repositories/user.py
from models import User
from schemas import UserCreate, UserUpdate
from repositories.base import BaseRepository
classUserRepository(BaseRepository[User]):
def__init__(self, db):
super().__init__(User, db)
defget_by_email(self, email: str) -> User:
returnself.db.query(self.model).filter(self.model.email == email).first()
# 可以添加更多特定于用户的查询方法
在路由中使用仓库
# api/users.py
from fastapi import APIRouter, Depends
from sqlalchemy.orm import Session
from repositories.user import UserRepository
from schemas import UserCreate, UserUpdate, User
from database import get_db
router = APIRouter()
@router.get("/users/{user_id}", response_model=User)
defread_user(user_id: int, db: Session = Depends(get_db)):
repo = UserRepository(db)
return repo.get(user_id)
@router.post("/users/", response_model=User)
defcreate_user(user: UserCreate, db: Session = Depends(get_db)):
repo = UserRepository(db)
return repo.create(user)
# 其他路由...
3. 依赖注入模式
创建可注入的服务类
# dependencies/services.py
from fastapi import Depends
from sqlalchemy.orm import Session
from services.user_service import UserService
from database import get_db
def get_user_service(db: Session = Depends(get_db)):
return UserService(db)
在路由中使用依赖注入
# api/users.py
from fastapi import APIRouter
from dependencies.services import get_user_service
from schemas import UserCreate, UserUpdate, User
router = APIRouter()
@router.get("/users/{user_id}", response_model=User)
defread_user(user_id: int, user_service: UserService = Depends(get_user_service)):
return user_service.get_user(user_id)
@router.post("/users/", response_model=User)
defcreate_user(user: UserCreate, user_service: UserService = Depends(get_user_service)):
return user_service.create_user(user)
# 其他路由...
最佳实践建议
-
- 分层清晰:保持路由层、服务层、数据访问层的分离
-
- 单一职责:每个类/方法只做一件事
-
- 依赖注入:利用FastAPI的依赖注入系统管理依赖
-
- 类型提示:充分利用Python的类型提示提高代码可读性
-
- 异常处理:在服务层处理业务异常,路由层处理HTTP异常
这种类组织方式使得代码更易于测试、维护和扩展,特别是在大型项目中优势明显。
本文使用 文章同步助手 同步