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

如何在AWS Glue中将JSON字典键转为表格的ID字段?

}

希望通过AWS Glue ETL任务将其转换为如下格式的表格:

| ID       | attr_a | attr_b |
|----------|--------|--------|
| ID_001   | bla    | blub   |
| ID_002   | foo    | bar    |
| ...      |        |        |

但目前得到的表格格式如下:

| ID_001 | ID_002 | ... |
|--------|--------|-----|

在pandas中使用`df.transpose()`即可解决,但在自定义转换中获取的`DynamicFrameCollection`里遇到了困难。请问在Spark/AWS Glue中有没有首选的转换方法?或者有没有更好的方式将该数据导入Athena表格?

---

# 解决方案

## 一、Spark/AWS Glue ETL转换方法

### 方法1:DynamicFrame转Spark DataFrame处理
将Glue的DynamicFrame转为Spark DataFrame后,利用Spark内置函数完成结构转换,是通用且高效的方案:
```python
from awsglue.context import GlueContext
from pyspark.context import SparkContext

sc = SparkContext.getOrCreate()
glueContext = GlueContext(sc)

# 读取JSON文件(开启multiline支持单条大JSON)
dynamic_frame = glueContext.create_dynamic_frame.from_options(
    connection_type="s3",
    connection_options={"paths": ["s3://your-bucket/path/to/json/"]},
    format="json",
    format_options={"multiline": True}
)

# 转为Spark DataFrame
df = dynamic_frame.toDF()

# 获取所有顶层ID列名
id_columns = df.columns

# 构造stack表达式,将列维度数据转为行维度
stack_expr = f"stack({len(id_columns)}, " + ", ".join([f"'{col}', {col}.attr_a, {col}.attr_b" for col in id_columns]) + ")"
result_df = df.selectExpr(stack_expr).toDF("ID", "attr_a", "attr_b")

# 可选:转回DynamicFrame继续后续Glue操作
result_dynamic_frame = glueContext.create_dynamic_frame.from_df(result_df, glueContext, "transformed_result")

方法2:Glue原生FlatMap转换

直接在DynamicFrame上使用flatMap自定义转换逻辑,手动展开顶层键值对:

from awsglue.context import GlueContext
from pyspark.context import SparkContext

sc = SparkContext.getOrCreate()
glueContext = GlueContext(sc)

# 读取JSON文件(单条大JSON需开启multiline)
dynamic_frame = glueContext.create_dynamic_frame.from_options(
    connection_type="s3",
    connection_options={"paths": ["s3://your-bucket/path/to/json/"]},
    format="json",
    format_options={"multiline": True}
)

# 自定义展开函数:将单条大记录拆分为多条目标格式记录
def flatten_records(rec):
    flattened_list = []
    for id_key, attrs in rec.items():
        flattened_list.append({
            "ID": id_key,
            "attr_a": attrs.get("attr_a"),
            "attr_b": attrs.get("attr_b")
        })
    return flattened_list

# 执行flatMap转换
result_dynamic_frame = dynamic_frame.flatMap(flatten_records)

二、直接通过Athena导入并转换

无需经过Glue ETL,可直接在Athena中创建外部表并完成结构转换:

步骤1:创建临时原始表

CREATE EXTERNAL TABLE temp_raw_data (
  data map<string, struct<attr_a:string, attr_b:string>>
)
ROW FORMAT SERDE 'org.openx.data.jsonserde.JsonSerDe'
LOCATION 's3://your-bucket/path/to/json/'
TBLPROPERTIES ('has_encrypted_data'='false', 'serialization.format'='1');

步骤2:创建目标表并插入转换后的数据

-- 创建目标表
CREATE EXTERNAL TABLE target_data (
  ID string,
  attr_a string,
  attr_b string
)
ROW FORMAT SERDE 'org.openx.data.jsonserde.JsonSerDe'
LOCATION 's3://your-bucket/path/to/target-data/';

-- 插入转换后的数据,自动展开map中的键值对
INSERT INTO target_data
SELECT 
  map_keys(data)[idx] AS ID,
  map_values(data)[idx].attr_a AS attr_a,
  map_values(data)[idx].attr_b AS attr_b
FROM temp_raw_data
CROSS JOIN UNNEST(SEQUENCE(0, SIZE(map_keys(data))-1)) AS t(idx);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 13:33:16