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

FastAPI PostgreSQL删除操作触发500内部服务器错误排查

问题原因分析:PostgreSQL + FastAPI删除操作中cursor.fetchone()报错psycopg2.ProgrammingError: no results to fetch

核心原因

PostgreSQL的常规DELETE语句执行完成后,不会返回被删除的行数据。你的代码里执行完DELETE后直接调用cursor.fetchone(),但此时游标根本没有可获取的结果集——不管目标ID存在与否,只要是普通DELETE,都不会产生返回结果,所以必然触发no results to fetch的编程错误。

哪怕ID存在、记录确实被删除了,普通DELETE也不会返回任何数据,这就是为什么你看到记录被删但仍报500的原因。

解决方案

有两种靠谱的修正方式,根据你的需求选择:

方式1:获取被删除的行数据(用RETURNING子句)

如果需要拿到被删除的post内容,修改DELETE语句,加上RETURNING *让PostgreSQL返回被删除的行:

@app.delete("/posts/{id}", status_code=status.HTTP_204_NO_CONTENT)
def delete_post(id: int):
    print("ID IS ",id)
    # 加上RETURNING *,让DELETE返回被删除的行
    cursor.execute("""DELETE FROM public."Posts" WHERE id = %s RETURNING *""", (id,))
    deleted_post = cursor.fetchone()
    conn.commit()
    if deleted_post is None:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND,
                            detail=f"Post with {id} not found")
    return Response(status_code=status.HTTP_204_NO_CONTENT)

另外注意:id本身是int类型,不需要转成str(id),直接传(id,)更合理。

方式2:仅判断是否有行被删除(用cursor.rowcount)

如果不需要被删除的数据,只需要确认是否存在对应记录,直接用游标rowcount属性获取受影响的行数即可:

@app.delete("/posts/{id}", status_code=status.HTTP_204_NO_CONTENT)
def delete_post(id: int):
    print("ID IS ",id)
    cursor.execute("""DELETE FROM public."Posts" WHERE id = %s""", (id,))
    conn.commit()
    # 受影响行数为0,说明没有找到对应ID的记录
    if cursor.rowcount == 0:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND,
                            detail=f"Post with {id} not found")
    return Response(status_code=status.HTTP_204_NO_CONTENT)

这种方式不需要修改DELETE语句,更轻量。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 17:50:36