from fastapi import Query, Depends, HTTPException, APIRouter from sqlalchemy.orm import Session from sqlalchemy_fastapi_demo.dao.Score import ScoreDAO from sqlalchemy_fastapi_demo.database import get_db from sqlalchemy_fastapi_demo.scheme.Score import ScoreCreate, ScoreUpdate app_score=APIRouter() # 查询所有成绩 @app_score.get("/",summary='查询所有成绩') async def get_scores( skip: int = Query(0, ge=0, description="跳过的记录数"), limit: int = Query(100, ge=1, le=200, description="返回的最大记录数"), db: Session = Depends(get_db) ): scores=ScoreDAO.get_all(db, skip=skip, limit=limit) return scores # 查询单个数据 @app_score.get("/{stu_id}/{exam_id}",summary='查询单个成绩') async def get_score( stu_id: int, exam_id: int, db: Session = Depends(get_db) ): score=ScoreDAO.get_by_id(db, stu_id,exam_id) if not score: raise HTTPException(status_code=404, detail="学生不存在") return score # 创建学生 @app_score.post("/",summary='创建学生成绩') async def create_scores( score:ScoreCreate, db: Session = Depends(get_db) ): # 检查学生在不在学生表 existing_foreign_key=ScoreDAO.inspect_stu_id_unq(db, score.stu_id) if not existing_foreign_key: raise HTTPException(status_code=404, detail="该学生不存在") if existing_foreign_key.is_deleted == 1: raise HTTPException(status_code=404, detail="该学生不存在") # 检查成绩是否已被占用 existing_score=ScoreDAO.get_by_id(db, score.stu_id,score.exam_id) if existing_score: raise HTTPException(status_code=400, detail="学生成绩已存在,请勿重复添加") new_score=ScoreDAO.post_score(db,score) return new_score # 修改 @app_score.put("/{stu_id}/{exam_id}",summary='修改信息') async def update_scores( stu_id: int, exam_id: int, score:ScoreUpdate, db: Session = Depends(get_db) ): # 只允许修改成绩,学生id和考试次序不允许修改,SQLAlchemy不能直接更新联合主键本身 # 检查成绩是否已存在 existing_foreign_key = ScoreDAO.inspect_stu_id_unq(db, score.stu_id) if not existing_foreign_key: raise HTTPException(status_code=404, detail="该学生不存在") existing_score=ScoreDAO.get_by_id(db, stu_id,exam_id) if not existing_score: raise HTTPException(status_code=404, detail="学生成绩不存在") # 直接调用DAO更新,只更新score字段 b = ScoreDAO.put_score(db, stu_id, exam_id, score) return b # 修改成绩:支持修改 stu_id、exam_id、score;原理:删除旧记录,新增新记录 # stu_id、exam_id是联合主键。MySQL不允许update 直接修改主键字段,SQLAlchemy # 底层执行会抛数据库异常。所以采用「删旧、建新」的方案模拟修改 # 风险大 # 现在代码:删旧和新增是两次 # db.commit()。 # 如果删旧成功,新增中途崩掉,会出现旧数据没了,新数据没加上,数据丢失。 # 数据库这条记录实际上是新行,不是原来那一行。 # 如果别的表有外键引用这条成绩记录,这个方案会出问题(旧记录删掉,关联跟着没了)。 # @app_score.put("/{stu_id}/{exam_id}",summary='修改学生成绩(支持修改学生ID、考核序次、分数)') # async def update_scores( # stu_id: int, # exam_id: int, # score:ScoreUpdate, # db: Session = Depends(get_db) # ): # # 1.找到旧记录 # old_score = ScoreDAO.get_by_id(db, stu_id, exam_id) # if not old_score: # raise HTTPException(status_code=404, detail="待修改的成绩记录不存在") # # 2.确定新值:前端没传的字段,沿用旧记录的值 # new_stu = score.stu_id if score.stu_id is not None else old_score.stu_id # new_exam_id = score.exam_id if score.exam_id is not None else old_score.exam_id # new_score_val = score.score if score.score is not None else old_score.score # # 3.校验新stu_id学生是否存在 # if new_stu != old_score.stu_id: # stu_obj = ScoreDAO.inspect_stu_id_unq(db, new_stu) # if not stu_obj: # raise HTTPException(status_code=404, detail="目标学生不存在") # # 4.如果新主键组合和旧的不一样,要检查新组合是否冲突 # if (new_stu, new_exam_id) != (old_score.stu_id, old_score.exam_id): # conflict = ScoreDAO.get_by_id(db, new_stu, new_exam_id) # if conflict: # raise HTTPException(status_code=400, detail="新【学生ID+考核序次】组合已存在,不能使用") # # 核心逻辑:删除旧记录,新增一条全新记录 # # 删除旧数据 # ScoreDAO.delete_score(db, stu_id, exam_id) # # 组装成ScoreCreate对象,调用新增DAO # from sqlalchemy_fastapi_demo.scheme.Score import ScoreCreate # new_create_data = ScoreCreate( # stu_id=new_stu, # exam_id=new_exam_id, # score=new_score_val # ) # new_db_score = ScoreDAO.post_score(db, new_create_data) # return new_db_score # 删除 @app_score.delete("/{stu_id}/{exam_id}",summary='删除学生成绩') async def delete_scores( stu_id: int, exam_id: int, db: Session = Depends(get_db) ): score=ScoreDAO.delete_score(db, stu_id,exam_id) if not score: raise HTTPException(status_code=404, detail="学生成绩不存在") return {"msg":"删除成功"}