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

Python requests请求PostgREST传入错误JSON值无报错问题

问题原因分析

1. 首先是requests库的参数逻辑问题

requests.post的json参数本身就会自动完成Python对象到JSON字符串的序列化工作,同时自动添加Content-Type: application/json请求头,你提前调用json.dumps会导致双重序列化问题:

  • 正常代码:传入字典{"id": "13", "name":"nameinserted"},requests最终发送的请求体是标准JSON对象:
    {"id": "13", "name":"nameinserted"}
    
  • 异常代码:你先把字典转成了字符串'{"id": "13", "name":"nameinserted"}'再传给json参数,requests会把这个字符串再次序列化,最终发送的请求体是被转义的JSON标量字符串:
    "{\"id\": \"13\", \"name\":\"nameinserted\"}"
    
    这个内容是合法的JSON格式,所以不会触发JSON格式错误提示,但本质是单个字符串值,不是PostgREST预期的字段键值对对象。

2. PostgREST的处理逻辑

PostgREST接收POST插入请求时,预期的请求体是单条记录的JSON对象,或者多条记录的JSON数组。当收到合法的JSON标量(字符串、数字、布尔值等)时,会判定为没有提供任何字段赋值,尝试执行INSERT INTO 你的表名 DEFAULT VALUES;语句:

  • 如果你的表所有字段都允许为空或配置了默认值:会成功插入一条全默认值的记录,返回201。
  • 如果你的表存在非空且无默认值的字段(比如你设置的主键id):理论上PostgreSQL会抛出字段非空约束错误,PostgREST应该返回400状态码。你遇到返回201但无数据写入的情况,大概率是因为你的表配置了行级安全策略,无字段赋值的插入请求被策略静默拒绝,或者你使用的PostgREST版本存在对应边界场景的处理bug。
解决方法

要么直接把Python字典传给json参数,不要提前做json.dumps处理;如果要自己序列化,就把序列化后的字符串传给data参数,同时手动指定Content-Type: application/json头:

# 修正方案1 直接传字典(推荐)
r = requests.post(url, json=myjson_dict, headers=headers)

# 修正方案2 自己序列化的场景
myjson_str = json.dumps(myjson_dict)
headers["Content-Type"] = "application/json"
r = requests.post(url, data=myjson_str, headers=headers)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 17:15:05