如何从AWS Glue Dynamic Frame提取指定数据并解决下标报错
你遇到的TypeError: 'DynamicFrame' object is not subscriptable错误很常见,原因很直接:AWS Glue的DynamicFrame不是字典或数组类型,不能用['event_type']这种下标语法来直接获取字段值。而且你的逻辑本身也有问题——DynamicFrame是包含多行数据的分布式数据集,单个字段的取值可能有很多种,没法直接用整个数据集来做等于判断。
问题核心
你想要实现的是「按event_type字段的值,把不同类别的数据写入S3对应路径」,这需要用Glue/Spark分布式数据处理的正确姿势,而不是像操作单个变量那样访问数据集。
两种可行解决方案
方式1:自动按字段分区写入(推荐,符合大数据最佳实践)
Glue的写入API支持partitionKeys参数,可以自动根据指定字段的值在S3上创建分区文件夹,不需要手动判断和过滤,效率最高:
替换你原代码中的判断逻辑和数据输出部分:
# 删除原有的if-else判断代码,直接用分区写入 datasink2 = glueContext.write_dynamic_frame.from_options( frame = applymapping1, connection_type = "s3", connection_options = { "path": "s3://houpa-event-types/teste/", "partitionKeys": ["event_type"] # 按event_type自动生成分区文件夹 }, format = "json", transformation_ctx = "datasink2" )
执行后S3会自动生成类似s3://houpa-event-types/teste/event_type=search_active/、s3://houpa-event-types/teste/event_type=_session.stop/的路径,对应数据会自动写入对应分区。
方式2:手动提取唯一值并循环写入(适合自定义路径场景)
如果需要完全自定义路径格式(不是标准分区格式),可以先把DynamicFrame转成Spark DataFrame,提取唯一的event_type值后循环过滤写入:
# 把DynamicFrame转换为Spark DataFrame df = applymapping1.toDF() # 获取所有唯一的event_type值(注意:如果唯一值过多,此步骤可能影响性能) unique_event_types = df.select("event_type").distinct().rdd.flatMap(lambda x: x).collect() # 循环处理每个event_type for et in unique_event_types: # 过滤出当前event_type的数据 filtered_df = df.filter(df.event_type == et) # 转换回DynamicFrame filtered_dyf = DynamicFrame.fromDF(filtered_df, glueContext, f"filtered_dyf_{et}") # 写入对应路径 glueContext.write_dynamic_frame.from_options( frame = filtered_dyf, connection_type = "s3", connection_options = {"path": f"s3://houpa-event-types/teste/{et}"}, format = "json", transformation_ctx = f"datasink_{et}" )
补充说明
原代码中applymapping1['event_type']的写法完全误解了DynamicFrame的特性——如果只是想选择event_type字段,应该用applymapping1.select_fields(['event_type']),但这返回的还是一个DynamicFrame,不是单个值,没法直接用来判断路径。
内容的提问来源于stack exchange,提问作者Corvoloso

