无法从AWS Glue使用cx_oracle连接oracle数据库

plupiseo  于 2023-05-28  发布在  Oracle
关注(0)|答案(1)|浏览(190)

我试图使用cx_oracle从AWS胶水连接Oracle数据库,但我收到此错误消息
数据库错误:DPI-1047:找不到64位Oracle客户端库:“libclntsh.so:无法打开共享目标文件:没有这样的文件或目录“”。有关帮助,请参见https://cx-oracle.readthedocs.io/en/latest/user_guide/installation.html
我试着按文档下载so文件,并将其存储在S3中,S3已通过--extra-files参数链接到Glue,但仍然得到相同的错误消息
我试过这个stackoverflow question,也试过用s3 url设置rpath,但没有成功。任何想法都会很有帮助

6gpjuf90

6gpjuf901#

积分

这个答案是thisthis的汇编,以及评论中围绕前者的大量讨论。rpath补丁解决方案的功劳归于@harjeet-singh,上述答案的原作者,libaio的功劳归于@good-will,但是围绕这些解决方案仍然有一些步骤让人们感到困惑,所以这就是为什么我要在这里将所有内容合并为一个分步的答案。

后台

为了使用cx-Oracle从Python shell AWS Glue作业连接到Oracle数据库,我们需要将Oracle客户端库与之捆绑。此外,为了正确加载,库必须使用正确的rpath进行修补,因为在Glue运行时中,我们只能对/tmp进行文件系统写访问,这是我们的归档文件所在的位置,但cx-Oracle无法知道这一点,并且默认情况下需要不同的目录。而LD_LIBRARY_PATH黑客无法实现,因为我们无法控制如何启动Glue作业。

步骤指南

1.从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

1.解压缩存档

unzip instantclient-basic-linuxx64.zip

1.从归档文件中删除符号链接,并将它们指向的文件(在本例中为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:无法打开共享目标文件:没有此类文件或目录”
1.修补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

1.将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/

1.下载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

1.将存档和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

1.配置粘合作业
我假设你的胶水作业已经创建好了,我们只需要配置它。

  • 将存档的S3 URL放入“Referenced files path”配置参数
  • cx-Oracle wheel的S3 URL放入“Python库路径”配置参数中

1.在粘合作业中添加一些代码来设置库。必须在使用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机器上运行下面的命令(在最后替换你的bucket名称):

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配置作业。
希望任何读到这篇文章的人都能在第一次尝试时就做对,因为我肯定没有。

相关问题