Python用urllib POST API时PostgreSQL jsonb字段带引号问题求解
问题根因
当前代码出现jsonb字段被额外包裹引号的核心原因有两点:
- 调用
urllib.parse.urlencode处理请求参数时,嵌套的字典类型值会被直接转成Python字典的原生字符串表示(使用单引号包裹键值),不符合JSON要求的双引号语法规范 - 提交的参数为
application/x-www-form-urlencoded表单格式时,未对jsonb类型的嵌套字段做标准JSON序列化,后端接收到值后无法识别为JSON结构,只能按普通字符串写入,自动在外层包裹引号存入jsonb字段。
解决方案(纯Python原生实现,无需安装第三方依赖)
全程使用Python标准库实现,不需要安装pip包,提供两种适配不同后端要求的实现方式:
方案1:后端要求必须使用表单格式提交
对需要存入jsonb字段的嵌套值,提前用标准库json.dumps()序列化为标准JSON字符串,再进行表单编码,保证后端可以正常解析为JSON结构:
import urllib.parse import urllib.request import json def post_wo_requ(): post_data = { 'store': 'Jack', # 嵌套字典先序列化为标准JSON格式字符串 'store_detail': json.dumps({'Tel1':'00000', 'Tel2':'11111'}) } url = host + '/' + pg_table data = urllib.parse.urlencode(post_data).encode('utf-8') req = urllib.request.Request( url, data=data, headers={'Content-Type': 'application/x-www-form-urlencoded'} ) with urllib.request.urlopen(req) as resp: return resp.read()
方案2:后端支持JSON格式请求体(推荐)
绝大多数操作PostgreSQL的API都支持直接接收JSON格式请求体,这种方式不需要单独处理嵌套字段,直接将整个参数对象序列化为JSON提交即可,从根源避免字段类型识别错误:
import urllib.request import json def post_wo_requ(): post_data = { 'store': 'Jack', 'store_detail': {'Tel1':'00000', 'Tel2':'11111'} } url = host + '/' + pg_table # 整体序列化为标准JSON字节流 data = json.dumps(post_data).encode('utf-8') req = urllib.request.Request( url, data=data, headers={'Content-Type': 'application/json'} ) with urllib.request.urlopen(req) as resp: return resp.read()
注意:禁止直接用
str()转换Python字典作为JSON值传入,该方法输出的字符串使用单引号包裹键值,不符合JSON语法规范,后端解析器无法识别,会直接按普通字符串存储。所有JSON序列化操作必须使用json.dumps()完成,输出的双引号格式才是符合标准的JSON结构。
内容的提问来源于stack exchange,提问作者ziazo
相关产品推荐
相关产品推荐

