如何解决AWS Glue Job连接Salesforce时的依赖库版本冲突问题
问题描述
我参考了相关问题及博客内容,但因依赖库版本冲突,无法成功建立AWS Glue Job与Salesforce的连接。我希望使用simple_salesforce库(目前使用最广泛、被引用最多的库)来实现连接。以下代码在本地机器上可正常运行,但在AWS Glue中运行时出现两类错误:
1. Python Shell配置时的错误
ERROR: botocore 1.12.232 has requirement urllib3<1.26,>=1.20; python_version >= "3.4", but you'll have urllib3 1.26.2 which is incompatible.
2. Spark配置时的错误
Traceback (most recent call last): File "/tmp/bp-etl-crm-sparkV2", line 1, in <module> from simple_salesforce import Salesforce File "/tmp/simple_salesforce-1.10.1-py2.py3-none-any.whl/simple_salesforce/__init__.py", line 4, in <module> from .api import Salesforce, SFType File "/tmp/simple_salesforce-1.10.1-py2.py3-none-any.whl/simple_salesforce/api.py", line 18, in <module> from .login import SalesforceLogin File "/tmp/simple_salesforce-1.10.1-py2.py3-none-any.whl/simple_salesforce/login.py", line 16, in <module> from authlib.jose import jwt ModuleNotFoundError: No module named 'authlib'
运行的核心代码(本地测试凭证及连接均正常):
from simple_salesforce import Salesforce def main(): print("INIT") sf = Salesforce(username='username', password='pw', security_token='securitytoken', domain='test') res_bulk = sf.bulk.Account.query('SELECT Id, Name FROM Table') print(res_bulk) if __name__ == "__main__": main()
我已尝试的解决方法:
- 分别配置Glue 1.0的Python Shell作业和Glue 2.0的Spark作业,均因依赖问题失败;
- 降级simple-salesforce版本,但仍出现相同的urllib3版本不兼容错误;
- 下载低于1.26.2版本的urllib3并上传至S3,添加到作业依赖库中,但未生效(不清楚Glue对于自身预设库的版本优先级处理逻辑)。
请问我可能存在哪些操作失误,或者还有哪些可尝试的解决方法?
解决方案
针对Python Shell配置的urllib3版本冲突问题
这个问题的根源在于AWS Glue 1.0的Python Shell环境自带的botocore版本较低(1.12.232),强制要求urllib3 <1.26,但simple_salesforce默认安装的依赖会拉取更高版本的urllib3,导致版本冲突。你之前单独上传低版本urllib3未生效,大概率是因为Glue系统自带库的优先级高于你上传的依赖,或者你没有将所有兼容的依赖打包在一起。
可以尝试以下步骤:
打包兼容的依赖包
在本地创建一个与Glue 1.0一致的Python虚拟环境(比如Python 3.6),然后安装指定版本的依赖:pip install simple-salesforce==1.10.1 urllib3==1.25.11 botocore==1.12.232 --target ./dependencies然后将
dependencies文件夹下的所有内容打包成一个zip文件(比如salesforce-deps.zip),上传到S3的指定路径下。配置Glue作业依赖并调整加载优先级
在Glue Python Shell作业的「Python library path」中添加这个S3上的zip文件路径。同时,在作业代码开头添加以下代码,确保你的依赖包优先被加载:import sys import os # 解压后的依赖会放在/tmp目录下,手动添加到sys.path最前面 sys.path.insert(0, os.path.join('/tmp', 'salesforce-deps'))升级到Glue 3.0 Python Shell(推荐)
Glue 3.0的Python Shell环境自带的botocore版本更高(1.24.x),对应的urllib3版本要求是<1.27,刚好兼容你遇到的urllib3 1.26.2。如果业务允许,直接切换到Glue 3.0环境,可能不需要额外处理版本冲突。
针对Spark配置的authlib缺失问题
Glue 2.0的Spark环境默认没有安装authlib,而simple_salesforce 1.10.1版本开始依赖authlib处理JWT登录逻辑,所以会出现模块找不到的错误。你需要将simple_salesforce及其所有依赖(包括authlib)一起打包上传。
具体步骤:
打包完整依赖
在本地创建与Glue 2.0一致的Python虚拟环境(比如Python 3.7),安装所需依赖:pip install simple-salesforce==1.10.1 authlib==1.0.1 --target ./spark-dependencies将
spark-dependencies文件夹打包成zip文件(比如spark-salesforce-deps.zip),上传到S3。配置Glue Spark作业
在Glue Spark作业的「Python library path」中添加这个S3 zip路径。如果还是出现加载问题,可以在代码开头手动添加路径,参考Python Shell的处理方式。可选:降级到无authlib依赖的simple_salesforce版本
如果不想处理authlib的依赖,可以尝试降级到simple-salesforce==0.74.2(这个版本之前不依赖authlib),但需要注意这个版本可能不支持一些新的Salesforce API特性,需要根据你的业务需求判断是否适用。
通用注意事项
- 依赖版本一致性:确保本地打包依赖时使用的Python版本和Glue作业的Python版本完全一致(比如Glue 1.0用Python 3.6,Glue 2.0用Python 3.7,Glue 3.0用Python 3.9),否则可能出现兼容性问题。
- S3权限:确保Glue作业的IAM角色有访问S3依赖包路径的权限(需要
s3:GetObject等权限)。 - 避免依赖遗漏:打包依赖时尽量使用
--target参数将所有依赖放到同一个目录,避免遗漏间接依赖。
内容的提问来源于stack exchange,提问作者monkey intern

