FastAPI调用GET /appointments返回422 value_error.missing字段缺失错误
问题原因及修复方案
直接报错原因
你出现422错误的核心原因是main.py中的路由函数写得不符合FastAPI规范:
- FastAPI的普通路由函数不是类方法,不需要加
self参数 - FastAPI会把路由函数中没有指定来源(路径/依赖等)的参数默认解析为查询参数,你写了
self参数,访问接口时没有传入对应的self查询参数,就触发了字段缺失的422报错。
其他需要修复的多处错误
你还有多处文件职责混淆、代码错误需要同步修正:
- 文件命名完全颠倒:你现在的
Schemas.py里写的是CRUD数据库操作函数,crud.py里写的是Pydantic schema模型,完全搞反了两者的作用。 - Pydantic模型字段不匹配:你在schema(现在的crud.py)里定义的
Appointment模型主键是Appointment_id,但SQLAlchemy model里的Appointment主键字段是id,字段名不一致会导致ORM映射失败。 - Pydantic类型注解错误:
AppointmentBase里的DateTime = str(datetime)是错误写法,这是给字段赋默认值而不是声明类型,应该正确声明字段类型。 - db依赖没有注入:你已经定义了
get_db数据库连接依赖,但没有在路由函数中注入使用,根本拿不到数据库会话。 - 重复初始化FastAPI实例:
main.py里连续两次执行app = FastAPI(),第一次的实例配置会被覆盖。 - model重复定义Base:
Models.py里已经从database导入了Base,又重新声明Base = declarative_base(),会导致表创建逻辑异常。
具体修改步骤
1. 修正Models.py
去掉重复的Base声明:
# coding: utf-8 from sqlalchemy import Column, DateTime, ForeignKey, String, Table from sqlalchemy.dialects.mysql import INTEGER from sqlalchemy.orm import relationship from .database import Base # 已经导入就不用再声明了 metadata = Base.metadata # 后面的模型代码保持不变
2. 交换crud.py和Schemas.py的内容(修正文件职责)
- 把现在
crud.py里的Pydantic模型代码移到schemas.py里,修正字段和类型错误:
# schemas.py 正确内容 from typing import List, Optional from pydantic import BaseModel import datetime class AppointmentBase(BaseModel): DateTime: datetime.datetime # 正确声明类型 SessionLenght: int class Appointment(AppointmentBase): id: int # 和model里的主键字段名一致 Customer_CPR: int Tattooparlor_CVR: int Artist_CPR: int class Config: orm_mode = True class PaginatedAppointmentInfo(BaseModel): data: List[Appointment] = [] class Config: orm_mode = True
- 把现在
Schemas.py里的CRUD函数移到crud.py里:
# crud.py 正确内容 from typing import List from sqlalchemy.orm import Session from .models import Appointment def get_all_apointments(session: Session) -> List[Appointment]: return session.query(Appointment).all()
3. 修正main.py代码
from fastapi import Depends, FastAPI, HTTPException from sqlalchemy.orm import Session import uvicorn from . import models from .database import SessionLocal, engine from .schemas import Appointment, PaginatedAppointmentInfo from .crud import get_all_apointments # 只初始化一次app app = FastAPI() models.Base.metadata.create_all(bind=engine) # Dependency def get_db(): db = SessionLocal() try: yield db finally: db.close() # 修正路由函数,去掉self,注入db依赖 @app.get("/appointments", response_model=PaginatedAppointmentInfo) def list_apointments(db: Session = Depends(get_db)): apointments_list = get_all_apointments(db) return {"data": apointments_list} @app.get('/') def root_api(): return {"message": "Welcome to Balasundar's Technical Blog"}
验证
修改完成后重启服务,访问http://127.0.0.1:8000/appointments即可正常返回所有预约数据。
内容的提问来源于stack exchange,提问作者Nadia Hansen
相关产品推荐
相关产品推荐

