学分
这个答案是 this 和 this 的汇编,以及 cmets 中围绕前者的大量讨论。 @ 987654324@ 修补解决方案的功劳归于@harjeet-singh,上述答案的原作者和libaio 的功劳归于@good-will,但是围绕这些解决方案仍有一些步骤使人们感到困惑,因此这就是为什么我要在这里一步一步地整合所有内容。
背景
为了在 Python shell AWS Glue 作业中使用 cx-Oracle 连接到 Oracle 数据库,我们需要将 oracle 客户端库与其捆绑在一起。此外,必须使用正确的 rpath 修补库才能正确加载,因为在 Glue 运行时我们只有对 /tmp 的文件系统写入访问权限,这是我们的存档所在的位置,但 cx-Oracle 不能知道这一点,并且默认情况下需要一个不同的目录。并且LD_LIBRARY_PATH hack 无法实施,因为我们无法控制 Glue 作业的启动方式。
分步指南
- 从here 下载适用于 x86-64 Linux 的 Instant Client Basic ZIP 包。本指南使用版本 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
如果在完成整个指南并运行您的工作后,您仍然遇到类似库的问题,请对带有符号链接的其他文件执行相同操作
DatabaseError: DPI-1047: Cannot locate a 64-bit Oracle Client library: "libsomething.so: cannot open shared object file: No such file or directory"
- 修补
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
- 将
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
注意:如果有更新版本的libaio,您可能需要检查。
6. 压缩存档
cd ..
zip -T -r instantclient-basic-linuxx64_patched.zip instantclient_21_5/
- 下载
cx-Oraclewheel
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到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
- 配置您的胶水作业
我假设您的胶水作业已经创建,我们将对其进行配置。
- 将存档的 S3 URL 放入“引用文件路径”配置参数中
- 将 S3 URL 放入“Python 库路径”配置参数中的
cx-Oracle 轮子
- 在粘合作业中添加一些代码来设置库。
必须在使用
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 配置您的作业。
希望读到这篇文章的任何人都能在第一次尝试时就明白这一点,因为我确实没有。