Glue Job写入Redshift报错:Unrecognized scheme null;预期s3/s3n/s3a
我在执行Glue Job完成数据转换后,用以下代码把Spark DataFrame写入Redshift表:
dynamic_df = DynamicFrame.fromDF(df, glue_context, "dynamic_df") glue_context.write_dynamic_frame.from_jdbc_conf( frame=dynamic_df, catalog_connection=args['catalog_connection'], connection_options={"dbtable": args['dbschema'] + "." + args['dbtable'], "database": args['database']}, transformation_ctx="write_my_df" )
但收到了如下异常:
19/08/23 14:29:31 ERROR main: Traceback (most recent call last):
File "/mnt/yarn/usercache/root/appcache/application_1572375324962_0001/container_1572375324962_0001_01_000001/pyspark.zip/pyspark/sql/utils.py", line 63, in deco
return f(*a, **kw)
File "/mnt/yarn/usercache/root/appcache/application_1572375324962_0001/container_1572375324962_0001_01_000001/py4j-0.10.7-src.zip/py4j/protocol.py", line 328, in get_return_value
format(target_id, ".", name), value)
py4j.protocol.Py4JJavaError: An error occurred while calling o190.pyWriteDynamicFrame. : java.lang.IllegalArgumentException: Unrecognized scheme null; expected s3, s3n, or s3a
请问哪里操作错了?该怎么解决?
问题原因与解决方案
这个错误的核心原因很明确:Glue向Redshift写入数据时,必须依赖一个S3临时目录来中转数据——Glue会先把数据写到这个S3路径,再通过Redshift的COPY命令将数据加载到目标表中。你当前的配置里完全没有指定这个临时目录,所以程序抛出了"scheme null"的错误(因为它找不到合法的S3路径)。
解决这个问题只需要两步:
1. 在代码中添加S3临时目录配置
修改connection_options参数,加入tempDir字段,值为一个你有权限访问的S3路径,比如s3://your-bucket-name/temp/redshift-staging/。修改后的代码如下:
dynamic_df = DynamicFrame.fromDF(df, glue_context, "dynamic_df") glue_context.write_dynamic_frame.from_jdbc_conf( frame=dynamic_df, catalog_connection=args['catalog_connection'], connection_options={ "dbtable": args['dbschema'] + "." + args['dbtable'], "database": args['database'], "tempDir": "s3://your-s3-bucket/path/to/temp/folder/" # 新增这一行 }, transformation_ctx="write_my_df" )
2. 确保权限配置正确
- Glue角色权限:你的Glue Job所使用的IAM角色,必须拥有这个S3临时路径的
s3:PutObject、s3:GetObject、s3:DeleteObject权限(Glue会自动清理临时文件,所以需要删除权限)。 - Redshift访问权限:Redshift集群必须能够读取这个S3路径。你可以通过两种方式实现:
- 给Redshift关联的IAM角色添加S3读取权限;
- 在S3桶的权限策略中,允许Redshift集群的ARN访问该路径。
完成这两步后,重新运行Glue Job就能正常写入Redshift了。
内容的提问来源于stack exchange,提问作者Vzzarr

