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

如何通过Snowflake UDF将API返回的JSON数据保存为Snowflake表?

如何通过Snowflake UDF将API返回的JSON数据保存为Snowflake表?

看起来你遇到的问题是API返回的JSON里存在混合类型的字段,导致Pandas转成Arrow格式时触发了类型冲突错误。我来给你几个实用的解决方案,帮你把非结构化数据顺利存入Snowflake表:

方案1:直接存储整个JSON为单个VARIANT字段(最简单推荐)

Snowflake的VARIANT类型天生就是为非结构化JSON数据设计的,完全能处理嵌套、混合类型的内容。你不需要把JSON拆成多列,直接把整个API返回结果作为一行的单个字段插入即可:

import requests as rq
import snowflake.snowpark as snowpark

def getData (session: snowpark.Session):    
    apiurl = 'https://exmaple.com'
    header = {
        'Content-Type': 'application/x-www-form-urlencoded',        
        'Authorization': 'Bearer bearer_token'
    }
    response = rq.post(apiurl, headers = header)
    data = response.json()
    
    # 将整个JSON对象包装成Snowpark DataFrame的一行
    snow_df = session.create_dataframe([[data]], schema=["API_RESPONSE"])
    
    # 写入表,Snowflake会自动将该字段识别为VARIANT类型
    snow_df.write.mode("overwrite").save_as_table("DEV_1_RAW.SCHEMA!.RAW_SEGMENT")
    
    return "数据已成功保存"

之后你可以用Snowflake的JSON函数(比如GET_PATH、FLATTEN)来查询、解析这个VARIANT字段里的内容。

方案2:处理混合类型字段,统一转为JSON字符串

如果你还是想把JSON拆分成多列存储,但某些列存在混合类型(比如你提到的fimFranchisee),可以把这些有问题的列转成JSON字符串,让Pandas能正常处理:

import requests as rq
import pandas as pd
import snowflake.snowpark as snowpark
import json

def getData (session: snowpark.Session):    
    apiurl = 'https://exmaple.com'
    header = {
        'Content-Type': 'application/x-www-form-urlencoded',        
        'Authorization': 'Bearer bearer_token'
    }
    response = rq.post(apiurl, headers = header)
    data = response.json()
    
    df = pd.DataFrame(data)
    # 将混合类型的列转为JSON字符串,消除类型冲突
    df['fimFranchisee'] = df['fimFranchisee'].apply(lambda x: json.dumps(x) if x is not None else None)
    
    # 写入Snowflake表
    session.write_pandas(df, table_name= 'RAW_SEGMENT', database='DEV_1_RAW', schema='SCHEMA!', auto_create_table=True, overwrite=True)
    
    return "数据已成功保存"

写入后该字段会是STRING类型,之后你可以用Snowflake的PARSE_JSON函数把它转回VARIANT来操作。

方案3:用Snowpark DataFrame直接处理,跳过Pandas

Snowpark对Snowflake的原生数据类型支持更好,你可以跳过Pandas直接用Snowpark解析JSON,自动处理混合类型问题:

import requests as rq
import snowflake.snowpark as snowpark

def getData (session: snowpark.Session):    
    apiurl = 'https://exmaple.com'
    header = {
        'Content-Type': 'application/x-www-form-urlencoded',        
        'Authorization': 'Bearer bearer_token'
    }
    response = rq.post(apiurl, headers = header)
    data = response.json()
    
    # 根据API返回的是列表还是单个对象,创建Snowpark DataFrame
    if isinstance(data, list):
        snow_df = session.create_dataframe(data)
    else:
        snow_df = session.create_dataframe([data])
    
    # 写入表,Snowpark会自动推断合适的类型(混合类型字段会转为VARIANT)
    snow_df.write.mode("overwrite").save_as_table("DEV_1_RAW.SCHEMA!.RAW_SEGMENT")
    
    return "数据已成功保存"

错误原因说明

你遇到的pyarrow.lib.ArrowInvalid错误,本质是fimFranchisee列里同时存在列表和其他非列表的非空值(比如字典、字符串),PyArrow在转换时无法统一这种混合类型。而Snowflake的VARIANT类型专门用来处理这类非结构化数据,所以通过上面的方法将这类字段转为VARIANT或JSON字符串,就能解决类型冲突问题。

备注:内容来源于stack exchange,提问作者Victor Gallo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.14 17:29:29