FastAPI-Psycopg2添加数据报错:not all arguments converted during string formatting
问题
在FastAPI项目中,尝试向PostgreSQL的questions表插入数据,表包含integer类型的question_id和character varying类型的question字段。前9条数据可正常添加,但插入question_id为10的条目时触发错误:
File "/Users/t/PycharmProjects/API/venv/lib/python3.10/site-packages/psycopg2/extras.py", line 236, in execute return super().execute(query, vars) TypeError: not all arguments converted during string formatting
实现代码:
@router.post("/add-question", status_code=status.HTTP_201_CREATED) def new_question(data: new_question): id = data.question_id # 检查该ID是否已存在 cursor.execute(""" select * from questions where question_id = (%s)""", (str(id)),) value= cursor.fetchone() if value: raise HTTPException(status_code=status.HTTP_406_NOT_ACCEPTABLE, detail=f"已存在ID为 {id} 的问题") # 不存在则插入新数据 cursor.execute(""" insert into questions(question, question_id) values (%s,%s) returning *""", (data.question, data.question_id ) ) conn.commit() return { "state": "问题添加成功" }
Schema定义:
class new_question(BaseModel): question:str question_id:int
Postman请求示例:
{ "question": "如果钱不是问题,你会买什么?" , "question_id": 10 }
解决方案
错误根源在第一个cursor.execute的参数传递:(str(id))并不是元组,Python会将其解析成单个字符串str(id),而非包含一个元素的元组。当id为10时,字符串"10"会被拆成两个字符处理,SQL语句的%s仅需1个参数,实际却传入了2个字符,触发格式转换错误。前9条数据正常是因为数字1-9的字符串长度为1,刚好匹配参数数量,属于侥幸情况。
修改方法:将参数改为包含单个元素的元组,只需在括号后加一个逗号:
cursor.execute(""" select * from questions where question_id = (%s)""", (str(id),))
另外,question_id本身是integer类型,无需转成字符串,直接传id即可,优化后的检查代码:
cursor.execute(""" select * from questions where question_id = (%s)""", (id,))
完整修正后的代码:
@router.post("/add-question", status_code=status.HTTP_201_CREATED) def new_question(data: new_question): id = data.question_id # 检查该ID是否已存在 cursor.execute(""" select * from questions where question_id = (%s)""", (id,)) value= cursor.fetchone() if value: raise HTTPException(status_code=status.HTTP_406_NOT_ACCEPTABLE, detail=f"已存在ID为 {id} 的问题") # 不存在则插入新数据 cursor.execute(""" insert into questions(question, question_id) values (%s,%s) returning *""", (data.question, data.question_id) ) conn.commit() return { "state": "问题添加成功" }
内容的提问来源于stack exchange,提问作者HamzaDevXX
相关产品推荐
相关产品推荐

