FastAPI依赖函数返回数据调用报错:如何在函数间传递用户信息?
解决FastAPI中Depends获取当前用户后无法访问email的问题
我用FastAPI往PostgreSQL写数据,现在遇到个问题:我有个get_current_user()函数能返回带email的用户凭证,但不知道怎么在s3_create_upload_files()里拿到这个数据。需求是文件上传成功后,把用户邮箱和文件名存到数据库同一条记录里。
现有代码
get_current_user()
async def get_current_user( request: Request, db: Session = Depends(get_db), ): token = request.cookies.get("Authorization") if token is None: raise HTTPException(status_code=302, headers={"Location": '/auth/login'}) token = token.split("Bearer ")[-1] try: payload = jwt.decode(token, os.getenv('SECRET_KEY'), algorithms=["HS256"]) email: str = payload.get("sub") if email is None: raise HTTPException(status_code=302, headers={"Location": '/auth/login'}) except jwt.exceptions.ExpiredSignatureError: raise HTTPException(status_code=302, headers={"Location": '/auth/login'}) user = db.query(User).filter(User.email == email).first() if user is None: raise HTTPException(status_code=302, headers={"Location": '/auth/login'}) print(f'Email is {user.email}') return user # Ensure 'user' is a User object
s3_create_upload_files()
async def s3_create_upload_files( file: UploadFile = File(...), current_user: User = Depends(get_current_user), db: Session = Depends(get_db) ): ....CODE HERE,,,, # Insert data into the database after successful upload try: db = SessionLocal() file_data = User(filename=sanitized_filename, email=current_user.email) db.add(file_data) db.commit() except Exception as e: db.rollback() raise HTTPException(status_code=500, detail=str(e)) finally: db.close()
报错信息
前端报错:{"detail":"'Depends' object has no attribute 'email'"}
后端日志显示:INFO: 192.168.65.1:62133 - "POST /dashboard HTTP/1.1" 500 Internal Server Error
问题分析与修复
核心问题
- 模型混淆:你用用户模型
User来创建文件记录,这显然不对——用户模型的字段和文件记录需要的字段不匹配,应该单独定义文件记录模型。 - 重复创建数据库会话:已经通过
Depends(get_db)注入了会话,却手动创建SessionLocal(),导致会话管理混乱,同时可能干扰依赖注入的正常流程。
修复步骤
创建文件记录模型
单独定义存储文件信息的模型,不要复用用户模型:from sqlalchemy import Column, Integer, String from sqlalchemy.ext.declarative import declarative_base Base = declarative_base() class FileUpload(Base): __tablename__ = "file_uploads" id = Column(Integer, primary_key=True, index=True) filename = Column(String, index=True) email = Column(String, index=True)复用注入的数据库会话
删掉手动创建SessionLocal()的代码,直接使用函数参数中已注入的db会话。修正文件上传函数
修改后的s3_create_upload_files()代码:async def s3_create_upload_files( file: UploadFile = File(...), current_user: User = Depends(get_current_user), db: Session = Depends(get_db) ): # ... 你的S3上传逻辑 ... sanitized_filename = file.filename # 替换为你的文件名清洗逻辑 # 插入数据库 try: file_data = FileUpload(filename=sanitized_filename, email=current_user.email) db.add(file_data) db.commit() db.refresh(file_data) # 如需返回创建后的记录可添加此行 except Exception as e: db.rollback() raise HTTPException(status_code=500, detail=str(e)) # 无需手动关闭会话,FastAPI会自动管理依赖注入的会话生命周期验证依赖注入逻辑
确认get_db()的实现正确(标准生成器模式):def get_db(): db = SessionLocal() try: yield db finally: db.close()
内容的提问来源于stack exchange,提问作者user3324136
相关产品推荐
相关产品推荐

