FastAPI数据库提交错误处理优化:状态码、错误信息及会话管理
FastAPI天气读数接口错误处理优化方案
针对你提出的三个问题,逐一给出解决方案及优化后的代码:
一、提取并返回实际错误信息
SQLAlchemy异常对象包含具体错误详情,可通过str(e)提取,但要注意避免泄露数据库敏感信息(如账号、地址),可以按需截取或格式化后返回。
二、返回符合规范的错误状态码
- 若为服务器端数据库操作失败(如连接异常、事务错误),返回
500 Internal Server Error; - 若为客户端提交数据不符合数据库约束(如
sensor_id不存在、数值超出范围),返回400 Bad Request。
FastAPI中使用HTTPException可以直接抛出指定状态码和描述的异常,框架会自动生成标准响应格式。
三、数据库会话的正确管理
- 回滚:异常发生时必须执行回滚,避免会话残留未提交的脏数据;
- 关闭会话:无论请求成功或失败,都需要关闭会话以释放数据库连接。推荐用
finally块确保会话始终被关闭,或者使用上下文管理器简化操作。
优化后的完整代码
from fastapi import FastAPI, HTTPException from sqlalchemy.exc import SQLAlchemyError # 假设你已导入WeatherReading模型和session对象 app = FastAPI() @app.post("/reading") async def record_reading( sensor_id: int, fahrenheit: float, pressure: float, humidity: float, dew_point: float, battery: float ): weather_reading = WeatherReading( sensor_id=sensor_id, fahrenheit=fahrenheit, pressure=pressure, humidity=humidity, dew_point=dew_point, battery=battery ) try: session.add(weather_reading) session.commit() return {"message": "reading added"} except SQLAlchemyError as e: session.rollback() # 提取错误信息,可根据实际情况过滤敏感内容 error_detail = str(e).split("\n")[0] # 只取错误首行避免冗余 # 判断错误类型,区分客户端/服务器错误 if "foreign key constraint" in str(e).lower() or "check constraint" in str(e).lower(): raise HTTPException(status_code=400, detail=f"Invalid input: {error_detail}") else: raise HTTPException(status_code=500, detail=f"Database error: {error_detail}") finally: # 无论成功失败,确保会话关闭 session.close()
补充说明
- 使用
finally块保证会话一定会被关闭,避免连接池耗尽; - 通过判断错误关键词区分客户端和服务器错误,返回更精准的状态码;
- 错误信息做了简单截取,你可以根据实际需求调整格式化方式。
内容的提问来源于stack exchange,提问作者user179981
相关产品推荐
相关产品推荐

