使用Glue Job跨账号迁移DynamoDB:GSI空值写入问题咨询
DynamoDB跨账号迁移中GSI空值处理问题解答
问题原因解析
DynamoDB的全局二级索引(GSI)规则是:允许GSI键字段不存在(此时该条数据不会被纳入GSI索引),但不允许字段存在但值为NULL。你遇到的报错,是因为源表中的gsi0_pk是「字段存在但值为NULL」的状态,而通过DataFrame转DynamicFrame的过程中保留了这个NULL值字段,写入DynamoDB时明确传递了NULL值,触发了索引键非空约束。而正常业务写入时,通常是直接不传递该字段(而非传递NULL),所以不会触发错误。
可行解决方案
以下方案可以实现「空值时删除字段,非空时拼接前缀」的需求,无需设置占位默认值:
1. 在Spark DataFrame中处理字段逻辑
使用Spark SQL函数对gsi0_pk和gsi0_sk进行条件处理:非空值拼接前缀,空值则置为NULL。
from pyspark.sql.functions import when, concat, lit, col # 处理GSI字段:非空则拼接前缀,空则设为NULL processed_df = source_df.withColumn( "gsi0_pk", when(col("gsi0_pk").isNotNull(), concat(lit("XXX"), col("gsi0_pk"))).otherwise(None) ).withColumn( "gsi0_sk", when(col("gsi0_sk").isNotNull(), concat(lit("XXX"), col("gsi0_sk"))).otherwise(None) )
注意:如果源表中的空值是空白字符串(而非NULL),需要补充判断条件:
when(col("gsi0_pk").isNotNull() & (col("gsi0_pk") != ""), concat(lit("XXX"), col("gsi0_pk"))).otherwise(None)
2. 转换DynamicFrame时自动删除空值字段
将处理后的DataFrame转为DynamicFrame时,设置dropNullFields=True参数,该参数会自动移除所有值为NULL的字段,避免向DynamoDB传递NULL值:
target_dynamic_frame = DynamicFrame.fromDF(processed_df, glue_context, "target_df", dropNullFields=True)
这样处理后,空值的GSI字段会被完全移除,非空字段则携带前缀写入DynamoDB,完全符合你的需求。
内容的提问来源于stack exchange,提问作者Jie Zhao
相关产品推荐
相关产品推荐

