本文介紹了無法從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配置您的作業。
希望任何閱讀本文的人在第一次嘗試時都能正確理解,因為我肯定沒有。
這篇關于無法從AWS Glue使用CX_ORACLE連接Oracle數據庫的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,