AWS Glue读取混合类型DynamoDB表时列值为空的类型解析问题
解决AWS Glue读取DynamoDB混合类型列时的null值问题
问题背景
现有DynamoDB表数据如下:
+------------------+---------+---------------------+ | id |Column A | Column B| +------------------+---------+---------------------+ |1 | "155.2"| 400 | |2 | 100| 200 | |3 | "455.2"| 305.5 | |4 | "312.3"| 350 | +------------------+---------+---------------------+
其中Column A存在混合类型:id=2为数字类型,其余为字符串形式的数字。使用AWS Glue的DynamoDB连接器读取为Dynamic Frame后,执行dyf.toDf().show()发现Column A的字符串值全部变为null,Schema显示该列为string类型,后续用resolveChoice转换也无效——因为对应值已丢失。
解决方案
1. 修改DynamoDB连接参数,禁用自动类型推断
在connection_options中添加"dynamodb.resolveType": "none",该参数会让连接器保留DynamoDB原始的带类型标记的JSON结构,避免因自动类型推断不匹配导致非预期null值。修改后的连接配置如下:
def create_dynamic_frame(table_name): ddb_s3_bucket = <some-s3-bucket> ddb_table_arn = <some-table-arn> connection_options = { "dynamodb.export": "ddb", "dynamodb.unnestDDBJson": True, "dynamodb.tableArn": ddb_table_arn, "dynamodb.s3.bucket": ddb_s3_bucket, "dynamodb.s3.prefix": 'temporary/ddbexport/', "dynamodb.resolveType": "none" } dynamic_frame = glueContext.create_dynamic_frame.from_options( connection_type="dynamodb", connection_options=connection_options, transformation_ctx="dynamic_frame", ) return dynamic_frame dyf = create_dynamic_frame('test-table')
2. 手动解析混合类型列
此时Dynamic Frame会保留每个字段的原始类型结构(比如Column A会是包含S(字符串)或N(数字)键的嵌套对象),通过自定义映射函数统一处理:
from awsglue.dynamicframe import DynamicFrame def normalize_mixed_column(rec): if 'Column A' in rec: col_a = rec['Column A'] # 根据需求转换为字符串或数字,此处统一转为字符串 if 'S' in col_a: rec['Column A'] = col_a['S'] elif 'N' in col_a: rec['Column A'] = col_a['N'] return rec # 应用映射处理 processed_dyf = dyf.map(f=normalize_mixed_column, transformation_ctx="processed_dyf") # 验证结果 processed_dyf.toDf().show()
3. 替代方案:读取S3导出的DynamoDB JSON文件
若上述参数不生效,可先将DynamoDB表导出到S3为JSON格式,再用Glue的JSON连接器读取,保留完整类型标记后再解析:
# 读取S3上的DynamoDB导出JSON文件 json_dyf = glueContext.create_dynamic_frame.from_options( connection_type="s3", connection_options={"paths": ["s3://your-bucket/temporary/ddbexport/"], "recurse": True}, format="json", format_options={"multiline": True} ) # 复用上述映射函数处理混合类型 resolved_dyf = json_dyf.map(f=normalize_mixed_column, transformation_ctx="resolved_dyf")
内容的提问来源于stack exchange,提问作者Ishan Gote
相关产品推荐
相关产品推荐

