使用Glue向Redshift插入数据报Delimiter not found错误如何解决
针对Glue写入Redshift IDENTITY列列数不匹配问题的可行解决方案
方案1:在Glue DataFrame中添加product_key空占位列
这是最便捷的适配方案,由于你的product_key是GENERATED BY DEFAULT AS IDENTITY属性,写入时传入NULL值,Redshift会自动生成序列值,不需要手动维护:
- PySpark代码示例:
from pyspark.sql.functions import lit # 假设source_df是你读取到的4列源数据DataFrame adjusted_df = source_df.withColumn("product_key", lit(None).cast("int")) # 再将adjusted_df转为DynamicFrame执行upsert即可
- 注意:不要给该列传入非空有效值,否则Redshift会优先使用你传入的值,而非自动生成的IDENTITY序列。
方案2:写入时指定Redshift插入列列表
不需要修改DataFrame结构,直接在Glue的Redshift连接参数中指定要插入的业务列,底层COPY命令会自动将输入的4列映射到指定列,剩下的IDENTITY列由Redshift自动填充:
- Glue写入参数示例:
glue_context.write_dynamic_frame.from_jdbc_conf( frame = dynamic_frame, # 你的4列源数据DynamicFrame catalog_connection = "你的Redshift连接名称", connection_options = { "dbtable": "public.store", "database": "你的数据库名称", "extracopyoptions": "COLUMNS (sku, product_id, qty, stock_status)" }, redshift_tmp_dir = "s3://你的临时存储桶路径/" )
方案3:自定义MERGE语句实现Upsert
如果你的业务逻辑需要严格控制Upsert(比如按sku判断存在则更新、不存在则插入),可以直接通过Glue执行Redshift自定义SQL,不需要强制对齐列数:
- 先将源4列数据写入Redshift的临时staging表
- 执行MERGE语句完成Upsert:
MERGE INTO store t USING store_staging s ON t.sku = s.sku WHEN MATCHED THEN UPDATE SET product_id = s.product_id, qty = s.qty, stock_status = s.stock_status WHEN NOT MATCHED THEN INSERT (sku, product_id, qty, stock_status) VALUES (s.sku, s.product_id, s.qty, s.stock_status);
执行完后清空临时staging表即可。
注意事项
- 确认你的Redshift表
product_key属性为GENERATED BY DEFAULT AS IDENTITY,如果是GENERATED ALWAYS AS IDENTITY,写入时即使传NULL也会报错,需要调整建表属性。 - 所有方案都不需要手动维护IDENTITY列的序列值,Redshift会自动保证主键唯一性。
内容的提问来源于stack exchange,提问作者che144
相关产品推荐
相关产品推荐

