在FastAPI中使用类实现查询和业务逻辑

125 阅读3分钟

在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, GenericList
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, idint) -> 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, idint, 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, idint) -> 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)

# 其他路由...

最佳实践建议

    1. 分层清晰:保持路由层、服务层、数据访问层的分离
    1. 单一职责:每个类/方法只做一件事
    1. 依赖注入:利用FastAPI的依赖注入系统管理依赖
    1. 类型提示:充分利用Python的类型提示提高代码可读性
    1. 异常处理:在服务层处理业务异常,路由层处理HTTP异常

这种类组织方式使得代码更易于测试、维护和扩展,特别是在大型项目中优势明显。

本文使用 文章同步助手 同步