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

如何在Redshift的SUPER列插入无转义字符的JSON数据?

问题

我尝试将API返回的数据以JSON格式存储到Redshift表的SUPER类型列中。

我的请求代码:

data = requests.get(url=f'https://economia.awesomeapi.com.br/json/last/USD-BRL')

我的插入函数如下:

QUERY = f"""INSERT INTO {schema}.{table}(data) VALUES (%s)"""

conn = self.__get_conn()
cursor = conn.cursor()

print('INSERT DATA')
cursor.execute(query=QUERY, vars=([data, ]))
conn.commit()

当使用data.json()插入时,出现错误:psycopg2.ProgrammingError: can't adapt type 'dict'。于是我使用json.dumps(data.json())序列化后插入,但数据库中的数据带有转义字符,示例如下:

"{\"code\": \"USD\", \"codein\": \"BRL\", \"name\": \"Dólar Americano/Real Brasileiro\", \"high\": \"5.2768\", \"low\": \"5.1848\", \"varBid\": \"-0.0264\", \"pctChange\": \"-0.5\", \"bid\":"

我希望在Redshift中使用DBT通过JSON_PARSE()和CTE来结构化该数据集,但这些转义字符造成了阻碍。我忽略了什么?有没有其他实现方式?

表的DDL:

CREATE TABLE IF NOT EXISTS public.raw_currency
(
    id BIGINT  DEFAULT "identity"(105800, 0, '1,1'::text) ENCODE az64
    ,"data" SUPER   ENCODE zstd
    ,stored_at TIMESTAMP WITHOUT TIME ZONE   ENCODE az64
    ,error_log VARCHAR(65535)   ENCODE lzo
)
解决方案

核心问题

Redshift的SUPER类型支持直接存储原生JSON结构,但psycopg2默认无法直接适配Python字典。用json.dumps()插入时,相当于把JSON字符串作为普通文本存入SUPER列,导致出现转义字符,后续JSON_PARSE()无法正确解析。

正确实现方式

方式1:在SQL中用JSON_PARSE()转换

修改插入语句,将序列化后的JSON字符串传入,并用JSON_PARSE()转换为SUPER类型:

import json

# 获取API返回的字典数据
json_data = data.json()
# 序列化为JSON字符串
json_str = json.dumps(json_data)

QUERY = f"""INSERT INTO {schema}.{table}(data) VALUES (JSON_PARSE(%s))"""

conn = self.__get_conn()
cursor = conn.cursor()
cursor.execute(query=QUERY, vars=(json_str,))
conn.commit()

插入后SUPER列会存储原生JSON结构,无转义字符,后续用DBT处理时可直接访问SUPER属性,无需额外解析。

方式2:使用psycopg2的Json适配器

psycopg2提供psycopg2.extras.Json类,可直接将Python字典适配为Redshift可识别的JSON格式:

from psycopg2.extras import Json

# 获取API返回的字典数据
json_data = data.json()

QUERY = f"""INSERT INTO {schema}.{table}(data) VALUES (%s)"""

conn = self.__get_conn()
cursor = conn.cursor()
cursor.execute(query=QUERY, vars=(Json(json_data),))
conn.commit()

这种方式无需手动序列化,适配器自动处理字典到SUPER类型的转换,插入数据为原生JSON结构。

额外优化:填充stored_at字段

表中包含stored_at字段,建议插入时自动填充当前时间,可在SQL中使用GETDATE():

# 配合上面任意一种方式修改插入语句
QUERY = f"""INSERT INTO {schema}.{table}(data, stored_at) VALUES (%s, GETDATE())"""

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 06:45:34