You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

FastAPI对接MongoDB按时间范围查询触发InvalidId错误如何解决

问题定位与修复方案

问题原因定位

  • 路由参数匹配错误:你采用的/{date_from}_{date_to}路径写法,FastAPI无法自动以下划线为分隔符拆分两个日期参数,会把整个2021-01-01_2021-12-31识别为单个date_from参数的值,同时date_to参数缺失。如果接口同路径下存在/{request_id}这类默认匹配ObjectId的路由,就会触发该路由的参数解析逻辑,将整个日期字符串尝试转为ObjectId,抛出你遇到的bson.errors.InvalidId报错。
  • 参数未声明类型:你没有给路由参数标注date类型,FastAPI无法自动将传入的日期字符串转为Python的date类型,后续和MongoDB中存储的日期类型字段比对会出现类型不匹配问题。
  • MongoDB查询逻辑错误:range()函数仅支持数字范围迭代,不能接收MongoDB的find游标作为参数,且时间范围查询需要使用MongoDB的查询运算符$gte(大于等于)和$lte(小于等于),不能分开两次调用find。

具体修复步骤

1. 路由(Route.py)修改

将路径参数改为斜杠分隔,同时明确标注参数类型,避免参数匹配错误:

from datetime import date
from fastapi import Path

@router.get("/{date_from}/{date_to}")
async def get_request_year(
    date_from: date = Path(..., description="开始日期,格式为YYYY-MM-DD"),
    date_to: date = Path(..., description="结束日期,格式为YYYY-MM-DD")
):
    request = await retrive_year_requests(date_from, date_to)
    if request:
        return request
    return ErrorRequestModel("An error occurred.", 404, "request doesn't exist.")

修改后访问路径变为http://localhost:8000/request/2021-01-01/2021-12-31。

2. 数据库查询(database.py)修改

修正MongoDB的时间范围查询逻辑:

async def retrive_year_requests(date_from: date, date_to: date):
    requests = []
    # 单条查询命中时间区间内的所有数据
    query = {"dates": {"$gte": date_from, "$lte": date_to}}
    async for request in request_collection.find(query):
        requests.append(request_helper(request))
    return requests

3. 可选:避免同路径路由冲突

如果你的路由文件中还有@router.get("/{request_id}")这类接收单个参数的路由,建议给参数加正则限制,确保只匹配ObjectId格式的参数:

from fastapi import Path

@router.get("/{request_id}")
async def get_single_request(
    request_id: str = Path(..., regex=r"^[0-9a-fA-F]{24}$")
):
    # 单条数据查询逻辑

内容的提问来源于stack exchange,提问作者Artur_marc

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 09:06:07