切换至AWS Secrets Manager后Glue ETL Job报getCatalogSource.None.get错误
问题:AWS Glue切换到Secrets Manager认证后ETL Job报错
None.get 原本在AWS Glue连接中使用用户名/密码认证,切换为AWS Secrets Manager后,运行ETL Job时出现如下错误:
An error occurred while calling o89.getCatalogSource. None.get
但连接和爬虫均可正常工作。
此前正常运行的ETL Job脚本如下:
import sys from awsglue.transforms import * from awsglue.utils import getResolvedOptions from pyspark.context import SparkContext from awsglue.context import GlueContext from awsglue.job import Job args = getResolvedOptions(sys.argv, ["JOB_NAME"]) sc = SparkContext() glueContext = GlueContext(sc) spark = glueContext.spark_session job = Job(glueContext) job.init(args["JOB_NAME"], args) # Script generated for node PostgreSQL PostgreSQL_node1663615620851 = glueContext.create_dynamic_frame.from_catalog( database="pg-db", table_name="postgres_schema_table", transformation_ctx="PostgreSQL_node1663615620851", )
日志中的错误信息
2022-09-19 19:28:19,322 ERROR [main] glue.ProcessLauncher (Logging.scala:logError(73)): Python执行错误: 回溯 (最近的调用最后): 文件 "/tmp/FC 2 job.py", 第19行, 在 <module>中 transformation_ctx="PostgreSQL_node1663615620851", 文件 "/opt/amazon/lib/python3.6/site-packages/awsglue/dynamicframe.py", 第629行, 在 from_catalog中 return self._glue_context.create_dynamic_frame_from_catalog(db, table_name, redshift_tmp_dir, transformation_ctx, push_down_predicate, additional_options, catalog_id, **kwargs) 文件 "/opt/amazon/lib/python3.6/site-packages/awsglue/context.py", 第186行, 在 create_dynamic_frame_from_catalog中 makeOptions(self._sc, additional_options), catalog_id), 文件 "/opt/amazon/spark/python/lib/py4j-0.10.9-src.zip/py4j/java_gateway.py", 第1305行, 在 __call__中 answer, self.gateway_client, self.target_id, self.name) 文件 "/opt/amazon/spark/python/lib/pyspark.zip/pyspark/sql/utils.py", 第111行, 在 deco中 return f(*a, **kw) 文件 "/opt/amazon/spark/python/lib/py4j-0.10.9-src.zip/py4j/protocol.py", 第328行, 在 get_return_value中 format(target_id, ".", name), value) py4j.protocol.Py4JJavaError: 调用o89.getCatalogSource时发生错误。 : java.util.NoSuchElementException: None.get at scala.None$.get(Option.scala:349) at scala.None$.get(Option.scala:347) at com.amazonaws.services.glue.util.DataCatalogWrapper.$anonfun$getJDBCConf$1(DataCatalogWrapper.scala:208) at scala.util.Try$.apply(Try.scala:209) at com.amazonaws.services.glue.util.DataCatalogWrapper.getJDBCConf(DataCatalogWrapper.scala:199) at com.amazonaws.services.glue.GlueContext.getGlueNativeJDBCSource(GlueContext.scala:485) at com.amazonaws.services.glue.GlueContext.getCatalogSource(GlueContext.scala:320) at com.amazonaws.services.glue.GlueContext.getCatalogSource(GlueContext.scala:185) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at py4j.reflection.MethodInvoker.invoke(MethodInvoker.java:244) at py4j.reflection.ReflectionEngine.invoke(ReflectionEngine.java:357) at py4j.Gateway.invoke(Gateway.java:282) at py4j.commands.AbstractCommand.invokeMethod(AbstractCommand.java:132) at py4j.commands.CallCommand.execute(CallCommand.java:79) at py4j.GatewayConnection.run(GatewayConnection.java:238) at java.lang.Thread.run(Thread.java:750)
2022-09-19 19:28:19,348 ERROR [main] glueexceptionanalysis.GlueExceptionAnalysisListener (Logging.scala:logError(9)): [Glue异常分析] { "事件": "GlueETLJobExceptionEvent", "时间戳": 1663615699344, "失败原因": "回溯 (最近的调用最后):\n 文件 \"/tmp/FC 2 job.py\", 第19行, 在 <module>中\n transformation_ctx=\"PostgreSQL_node1663615620851\",\n 文件 \"/opt/amazon/lib/python3.6/site-packages/awsglue/dynamicframe.py\", 第629行, 在 from_catalog中\n return self._glue_context.create_dynamic_frame_from_catalog(db, table_name, redshift_tmp_dir, transformation_ctx, push_down_predicate, additional_options, catalog_id, **kwargs)\n 文件 \"/opt/amazon/lib/python3.6/site-packages/awsglue/context.py\", 第186行, 在 create_dynamic_frame_from_catalog中\n makeOptions(self._sc, additional_options), catalog_id),\n 文件 \"/opt/amazon/spark/python/lib/py4j-0.10.9-src.zip/py4j/java_gateway.py\", 第1305行, 在 __call__中\n answer, self.gateway_client, self.target_id, self.name)\n 文件 \"/opt/amazon/spark/python/lib/pyspark.zip/pyspark/sql/utils.py\", 第111行, 在 deco中\n return f(*a, **kw)\n 文件 \"/opt/amazon/spark/python/lib/py4j-0.10.9-src.zip/py4j/protocol.py\", 第328行, 在 get_return_value中\n format(target_id, \".\", name), value)\npy4j.protocol.Py4JJavaError: 调用o89.getCatalogSource时发生错误。\n: java.util.NoSuchElementException: None.get\n\tat scala.None$.get(Option.scala:349)\n\tat scala.None$.get(Option.scala:347)\n\tat com.amazonaws.services.glue.util.DataCatalogWrapper.$anonfun$getJDBCConf$1(DataCatalogWrapper.scala:208)\n\tat scala.util.Try$.apply(Try.scala:209)\n\tat com.amazonaws.services.glue.util.DataCatalogWrapper.getJDBCConf(DataCatalogWrapper.scala:199)\n\tat com.amazonaws.services.glue.GlueContext.getGlueNativeJDBCSource(GlueContext.scala:485)\n\tat com.amazonaws.services.glue.GlueContext.getCatalogSource(GlueContext.scala:320)\n\tat com.amazonaws.services.glue.GlueContext.getCatalogSource(GlueContext.scala:185)\n\tat sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\n\tat sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)\n\tat sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)\n\tat java.lang.reflect.Method.invoke(Method.java:498)\n\tat py4j.reflection.MethodInvoker.invoke(MethodInvoker.java:244)\n\tat py4j.reflection.ReflectionEngine.invoke(ReflectionEngine.java:357)\n\tat py4j.Gateway.invoke(Gateway.java:282)\n\tat py4j.commands.AbstractCommand.invokeMethod(AbstractCommand.java:132)\n\tat py4j.commands.CallCommand.execute(CallCommand.java:79)\n\tat py4j.GatewayConnection.run(GatewayConnection.java:238)\n\tat java.lang.Thread.run(Thread.java:750)\n", "堆栈跟踪": [ { "声明类": "get_return_value", "方法名": "format(target_id, \".\", name), value)", "文件名": "/opt/amazon/spark/python/lib/py4j-0.10.9-src.zip/py4j/protocol.py", "行号": 328 }, { "声明类": "deco", "方法名": "return f(*a, **kw)", "文件名": "/opt/amazon/spark/python/lib/pyspark.zip/pyspark/sql/utils.py", "行号": 111 }, { "声明类": "__call__", "方法名": "answer, self.gateway_client, self.target_id, self.name)", "文件名": "/opt/amazon/spark/python/lib/py4j-0.10.9-src.zip/py4j/java_gateway.py", "行号": 1305 }, { "声明类": "create_dynamic_frame_from_catalog", "方法名": "makeOptions(self._sc, additional_options), catalog_id),", "文件名": "/opt/amazon/lib/python3.6/site-packages/awsglue/context.py", "行号": 186 }, { "声明类": "from_catalog", "方法名": "return self._glue_context.create_dynamic_frame_from_catalog(db, table_name, redshift_tmp_dir, transformation_ctx, push_down_predicate, additional_options, catalog_id, **kwargs)", "文件名": "/opt/amazon/lib/python3.6/site-packages/awsglue/dynamicframe.py", "行号": 629 }, { "声明类": "<module>", "方法名": "transformation_ctx=\"PostgreSQL_node1663615620851\",", "文件名": "/tmp/FC 2 job.py", "行号": 19 } ], "最后执行行号": 19, "脚本": "FC 2 job.py" }
解决方法
1. 检查Glue Job执行角色的Secrets Manager权限
爬虫和Glue Job使用的角色可能不同,即使爬虫能正常工作,Job角色可能缺少访问Secrets Manager的权限:
- 登录IAM控制台,找到该Glue Job的执行角色
- 添加
secretsmanager:GetSecretValue权限,资源指定目标Secret的ARN(注意Secret ARN可能带随机后缀,可使用通配符-*匹配) - 示例权限策略:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "secretsmanager:GetSecretValue", "Resource": "arn:aws:secretsmanager:<你的区域>:<你的账号ID>:secret:<Secret名称>-*" } ] }
2. 验证Secrets Manager中的Secret格式
Glue要求Secret的JSON结构包含username和password字段,否则无法提取认证信息:
- 打开Secrets Manager控制台,查看目标Secret的内容
- 确保格式如下:
{ "username": "数据库用户名", "password": "数据库密码" }
- 如果使用了自定义键名,需在Glue连接配置中设置对应的字段映射(部分数据库连接支持此功能)
3. 确认Glue连接的Secrets Manager配置正确
检查连接是否正确关联了Secret:
- 打开Glue控制台,编辑对应的JDBC连接
- 确认已勾选“使用AWS Secrets Manager存储用户名和密码”,并且Secret ARN填写正确
- 点击“测试连接”验证能否正常访问数据库
4. 升级Glue版本
旧版本Glue可能存在Secrets Manager兼容性问题:
- 在Glue Job配置中,选择Glue版本3.0及以上
- 重新运行Job测试
内容的提问来源于stack exchange,提问作者Brahim BEN ADDI
相关产品推荐
相关产品推荐

