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

使用Python调用Poke API创建SQL表时遇TypeError报错求助

问题:使用Python存储Poke API数据到SQL表时JSON序列化报错

尝试用Python调用Poke API,将前100个宝可梦信息存入PostgreSQL的JSONB字段,代码如下:

import psycopg2, json, requests, hidden

# Load secrets
secrets = hidden.secrets()

conn = psycopg2.connect(host=secrets['host'],
        port=secrets['port'],
        database=secrets['database'],
        ...,
        connect_timeout=3)

cur = conn.cursor()

defaulturl = 'https://pokeapi.co/api/v2/pokemon?limit=100&offset=0'


sql = '''
CREATE TABLE IF NOT EXISTS pokeapi
(id SERIAL, body JSONB); 
'''

cur.execute(sql)

response = requests.get(defaulturl)
js = response.json() 


results = js['results'] 



for x in range(len(results)):
    body = requests.get(results[x]['url'])
    js_body = json.dumps(body) 
    sql = f"INSERT INTO pokeapi (body) VALUES ('{js_body}'::JSONB)";
    cur.execute(sql, (defaulturl))

print('Closing database connection...')
conn.commit()
cur.close() 

运行时报错:

TypeError: Object of type Response is not JSON serializable

错误出现在js_body = json.dumps(body)这一行。


错误原因

requests.get()方法返回的是Response对象,它包含响应状态码、头部、内容等元信息,并不是直接可序列化的JSON数据。json.dumps()只能处理Python原生数据类型(如字典、列表等),无法直接序列化Response对象,因此抛出该错误。

修复方案及修正代码

针对问题做以下核心修改:

  1. 获取可序列化的JSON数据:调用Response对象的.text直接获取响应的JSON字符串,或用.json()转为字典后再序列化;
  2. 规避SQL注入风险:废弃字符串格式化拼接SQL的方式,改用参数化查询传递数据;
  3. 修正执行参数格式:确保参数元组格式正确(单个元素需加逗号),且参数与SQL占位符对应。

修正后的代码:

import psycopg2, json, requests, hidden

# Load secrets
secrets = hidden.secrets()

conn = psycopg2.connect(host=secrets['host'],
        port=secrets['port'],
        database=secrets['database'],
        user=secrets['user'],
        password=secrets['password'],
        connect_timeout=3)

cur = conn.cursor()

defaulturl = 'https://pokeapi.co/api/v2/pokemon?limit=100&offset=0'

# 创建表
sql = '''
CREATE TABLE IF NOT EXISTS pokeapi
(id SERIAL, body JSONB); 
'''
cur.execute(sql)

# 获取宝可梦列表
response = requests.get(defaulturl)
js = response.json() 
results = js['results'] 

for result in results:
    # 获取单个宝可梦的JSON响应文本
    pokemon_response = requests.get(result['url'])
    pokemon_json_str = pokemon_response.text
    
    # 参数化插入,避免SQL注入
    sql = "INSERT INTO pokeapi (body) VALUES (%s::JSONB)"
    cur.execute(sql, (pokemon_json_str,))  # 注意元组的逗号

print('Closing database connection...')
conn.commit()
cur.close()
conn.close()  # 补充关闭数据库连接

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 06:45:51