【问题标题】:Unable to connect oracle database using cx_oracle from AWS Glue无法使用 AWS Glue 中的 cx_oracle 连接 oracle 数据库
【发布时间】:2022-04-27 10:14:10
【问题描述】:

我正在尝试使用 cx_oracle 从 AWS 胶水连接 oracle 数据库,但我收到此错误消息

DatabaseError:DPI-1047:找不到 64 位 Oracle 客户端库:“libclntsh.so:无法打开共享对象文件:没有这样的文件或目录”。请参阅https://cx-oracle.readthedocs.io/en/latest/user_guide/installation.html 寻求帮助

我尝试根据文档下载so文件并将其存储在已使用--extra-files参数链接到Glue的S3中,但仍然收到相同的错误消息

我已经尝试过这个 stackoverflow question 并且还尝试使用 s3 url 设置 rpath 但没有成功。任何想法都会有帮助

【问题讨论】:

  • 在您提到的一个问题中,有一点是不支持符号链接,例如给出了 libclntsh.so。我想你可以在那里得到一些见解。

标签: oracle amazon-web-services aws-glue


【解决方案1】:

学分

这个答案是 thisthis 的汇编,以及 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 作业的启动方式。

分步指南

  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

如果在完成整个指南并运行您的工作后,您仍然遇到类似库的问题,请对带有符号链接的其他文件执行相同操作

DatabaseError: DPI-1047: Cannot locate a 64-bit Oracle Client library: "libsomething.so: cannot open shared object file: No such file or directory"

  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-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
  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 放入“引用文件路径”配置参数中
  • 将 S3 URL 放入“Python 库路径”配置参数中的 cx-Oracle 轮子
  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 机器上运行此程序(最后替换您的存储桶名称):

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 配置您的作业。

希望读到这篇文章的任何人都能在第一次尝试时就明白这一点,因为我确实没有。

【讨论】:

    猜你喜欢
    • 2019-12-27
    • 1970-01-01
    • 2020-02-06
    • 2020-08-10
    • 1970-01-01
    • 2018-08-08
    • 1970-01-01
    • 1970-01-01
    • 2021-10-04
    相关资源
    最近更新 更多