无法从AWS Glue使用CX_ORACLE连接Oracle数据库
我正在尝试使用cx_oracle从AWS GLue连接Oracle数据库,但收到此错误消息
数据库错误:DPI-1047:找不到64位Oracle客户端库:";libclntsh.so:无法打开共享对象文件:没有这样的文件或目录。有关帮助,请参阅https://cx-oracle.readthedocs.io/en/latest/user_guide/installation.html
我尝试按照文档下载so文件,并将其存储在S3中,该文件已使用--Extra-Files参数链接到Glue,但仍收到相同的错误信息
我已经尝试了这个堆栈溢出question,并尝试使用S3url设置rPath,但没有成功。任何想法都会很有帮助
解决方案
学分
这个答案是this和this的汇编,以及评论中围绕前者的大量讨论。rpath
修补解决方案的功劳归功于@Harjeet-Singh,他是上述答案的原始作者,libaio
归功于@Good-Will,但围绕这些解决方案仍然有一些步骤让人感到困惑,所以这就是为什么我将在这里将所有内容汇总到一个逐步的答案中。
背景
为了使用cx-Oracle
从一个Python外壳AWS Glue作业连接到Oracle数据库,我们需要将Oracle客户端库与它捆绑在一起。此外,库必须使用正确的rpath
打补丁才能正确加载,因为在Glue运行时,我们只有/tmp
的文件系统写访问权限,这是我们的归档所在的位置,但cx-Oracle
不知道这一点,并且默认情况下需要一个不同的目录。无法实施LD_LIBRARY_PATH
黑客攻击,因为我们无法控制如何启动粘合作业。分步指南
- 从here下载适用于x86-64 Linux的即时客户端基本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
如果在完成整个指南并运行您的作业后,库仍然有问题,请使用符号链接对其他文件执行相同的操作
数据库错误:DPI-1047:找不到64位Oracle客户端库:&qot;libomething.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
- 将
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-Oracle
滚轮
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放到配置参数中的
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配置您的作业。
希望任何阅读本文的人在第一次尝试时都能正确理解,因为我肯定没有。
相关文章