Credits
这个答案是一个汇编this and this评论中围绕前者进行了大量讨论。信用为rpath
修补解决方案交给@harjeet-singh,他是上述答案的原作者,libaio
致@good-will,但这些解决方案仍然有一些步骤让人们感到困惑,所以这就是为什么我将在这里将所有内容合并为一个逐步的答案。
背景
为了使用以下命令连接到 Oracle 数据库cx-Oracle
从 Python shell AWS Glue 作业中,我们需要将 Oracle 客户端库与其捆绑在一起。此外,库必须使用正确的补丁rpath
为了正确加载,因为在 Glue 运行时我们只有文件系统写访问权限/tmp
,这就是我们的档案所在的位置,但是cx-Oracle
无法知道这一点,并且默认情况下需要不同的目录。还有LD_LIBRARY_PATH
hack 无法实现,因为我们无法控制 Glue 作业的启动方式。
分步指南
- 下载适用于 x86-64 Linux 的 Instant Client Basic ZIP 包:here。本指南使用版本21.5.0.0.0
wget https://download.oracle.com/otn_software/linux/instantclient/instantclient-basic-linuxx64.zip
- 解压存档
unzip instantclient-basic-linuxx64.zip
- 从存档中删除符号链接并移动它们指向的文件(在本例中
libclntsh.so.21.1
到您使用时要查找的那个cx-Oracle
: libclntsh.so
)。这样做是因为无论动态加载这些库,显然都不会解析符号链接。也许将来会,但我必须这样做才能让它发挥作用。
cd instantclient_21_5/
find . -type l -name "libclntsh.so*" -delete
mv libclntsh.so.21.1 libclntsh.so
如果在完成整个指南并运行您的作业后,您仍然遇到类似库的问题,请对带有符号链接的其他文件执行相同的操作
数据库错误:DPI-1047:无法找到 64 位 Oracle 客户端库:“libsomething.so:无法打开共享对象文件:没有这样的文件或目录”
- 修补
rpath
指向我们将在 Glue 作业内部使用的静态目录
例如,如果您的存档名为instant-client-basic-linux.x64-21.5.0.0.0
它包含一个名为的文件夹instantclient_21_5
与所有图书馆。当作业运行时,该存档将在以下随机目录中可用/tmp
(更多内容如下。我们需要在这些目录之一中找到我们的存档并将其解压缩到下面的静态目录中/tmp
, 例如/tmp/libs
。那么,你的rpath
将会/tmp/libs/instant-client-basic-linux.x64-21.5.0.0.0/instantclient_21_5
,因为它位于客户端库的绝对路径中。
sudo apt-get update
sudo apt-get install patchelf -y
patchelf --set-rpath /tmp/libs/instant-client-basic-linux.x64-21.5.0.0.0/instantclient_21_5 libclntsh.so
- Put
libaio.so.1
在档案中
cd ..
wget https://src.fedoraproject.org/lookaside/pkgs/libaio/libaio-0.3.110.tar.gz/2a35602e43778383e2f4907a4ca39ab8/libaio-0.3.110.tar.gz
tar xzvf libaio-0.3.110.tar.gz
cd libaio-0.3.110
make prefix=`pwd`/usr install
find ./usr/lib/ -type l -name "libclntsh.so*" -delete
mv ./usr/lib/libaio.so.1.0.1 ../instantclient_21_5/libaio.so.1
Note:您可能想检查一下较新版本的libaio
如果有的话。
6. 压缩存档
cd ..
zip -T -r instantclient-basic-linuxx64_patched.zip instantclient_21_5/
- 下载
cx-Oracle
wheel
wget https://files.pythonhosted.org/packages/a9/b7/c2d0223fb4f1013b090cf82f3ce56f36f33b79a48f9c33b36717c2977b04/cx_Oracle-8.3.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl
- 上传存档并
cx-Oracle
to S3
aws s3 cp instantclient-basic-linuxx64_patched.zip s3://<mybucket>/glue_libs
aws s3 cp cx_Oracle-8.3.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl s3://<mybucket>/glue_libs
- 配置您的 Glue 作业
我假设您的粘合作业已经创建,我们将对其进行配置。
- 将 S3 URL 放入“引用文件路径”配置参数中
- 将 S3 URL 放入
cx-Oracle
“Python库路径”配置参数中的wheel
- 在粘合作业中添加一些代码来设置库。
此代码必须在使用之前执行
cx-Oracle
。它可以在导入之后、使用之前执行。
遍历随机目录/tmp
,找到您创建的存档并将其解压到我们设置的静态目录中rpath
之前。然后初始化cx-Oracle
客户和您就可以开始了。
下面是一个实现示例:
import zipfile
from pathlib import Path
import cx_Oracle
filename = 'instantclient-basic-linuxx64_patched.zip'
oracle_archive = next(Path('./tmp').glob(f'**/{filename}'))
with zipfile.ZipFile(oracle_archive, 'r') as f:
Path('./tmp/libs').mkdir()
f.extractall('./tmp/libs')
cx_Oracle.init_oracle_client(lib_dir=f'/tmp/libs/{filename}/instantclient_21_5')
TLDR
在您的 Linux 计算机上运行此命令(最后替换您的存储桶名称):
wget https://download.oracle.com/otn_software/linux/instantclient/instantclient-basic-linuxx64.zip
unzip instantclient-basic-linuxx64.zip
cd instantclient_21_5/
find . -type l -name "libclntsh.so*" -delete
mv libclntsh.so.21.1 libclntsh.so
sudo apt-get update
sudo apt-get install patchelf -y
patchelf --set-rpath /tmp/libs/instant-client-basic-linux.x64-21.5.0.0.0/instantclient_21_5 instantclient_21_5/libclntsh.so
cd ..
wget https://src.fedoraproject.org/lookaside/pkgs/libaio/libaio-0.3.110.tar.gz/2a35602e43778383e2f4907a4ca39ab8/libaio-0.3.110.tar.gz
tar xzvf libaio-0.3.110.tar.gz
cd libaio-0.3.110
make prefix=`pwd`/usr install
find ./usr/lib/ -type l -name "libclntsh.so*" -delete
mv ./usr/lib/libaio.so.1.0.1 ../instantclient_21_5/libaio.so.1
cd ..
zip -T -r instantclient-basic-linuxx64_patched.zip instantclient_21_5/
wget https://files.pythonhosted.org/packages/a9/b7/c2d0223fb4f1013b090cf82f3ce56f36f33b79a48f9c33b36717c2977b04/cx_Oracle-8.3.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl
aws s3 cp instantclient-basic-linuxx64_patched.zip s3://<mybucket>/glue_libs/
aws s3 cp cx_Oracle-8.3.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl s3://<mybucket>/glue_libs/
按照上面的步骤 9 和 10 配置您的作业。
希望任何读过这篇文章的人都能在第一次尝试时就做对,因为我确实没有做到。