我试图构建一个Docker镜像来在运行时访问Oracle数据库,我收到以下错误消息:DPI-1047: Cannot locate a 64-bit Oracle Client library: "/oracle/instantclient/libclntsh.so: cannot open shared object file: No such file or directory".
在容器内部,实际上在/oracle/instantclient/libclntsh.so
处有一个符号链接
Dockerfile:
FROM python:3.12-slim
RUN apt-get update && \
apt-get install -y wget unzip libaio1
ARG ORACLE_HOME=/oracle
ARG ORACLE_CLIENT_HOME=${ORACLE_HOME}/instantclient
# Download and install Oracle instantclient
RUN mkdir /tmp/oracle && \
wget https://download.oracle.com/otn_software/linux/instantclient/1920000/instantclient-basic-linux.x64-19.20.0.0.0dbru.zip -P /tmp/oracle && \
unzip /tmp/oracle/instantclient-basic-* -d /tmp/oracle && \
mkdir ${ORACLE_HOME} && \
mv /tmp/oracle/instantclient_* ${ORACLE_CLIENT_HOME}
ENV LD_LIBRARY_PATH="${ORACLE_CLIENT_HOME}"
RUN pip install --upgrade pip && \
pip install pipenv
ENV PIPENV_VENV_IN_PROJECT=1
WORKDIR /app
ADD main.py Pipfile Pipfile.lock ./
RUN pipenv sync
ENTRYPOINT ["./.venv/bin/python", "main.py"]
CMD [""]
字符串
main.py:
import os
import oracledb
def print_db_version(db_config):
params = oracledb.ConnectParams(host=db_config['host'], port=db_config['port'], service_name=db_config['name'])
with oracledb.connect(user=db_config['username'], password=db_config['password'], params=params) as conn:
print(f'Database version: {conn.version}')
conn.close()
if __name__ == '__main__':
# Both calls below fail...
# oracledb.init_oracle_client()
oracledb.init_oracle_client(os.environ['LD_LIBRARY_PATH'])
db_config = {
'host': os.environ['DB_HOST'],
'port': os.environ['DB_PORT'],
'name': os.environ['DB_NAME'],
'username': os.environ['DB_USERNAME'],
'password': os.environ['DB_PASSWORD'],
}
print_db_version(db_config)
型
Pipfile:
[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"
[packages]
oracledb = "1.4.2"
型
命令行(最后一个允许浏览容器):
docker build -t my-version .
docker run my-version
docker run -it --entrypoint "" my-version bash
型
我不知道为什么这个错误弹出,而库实际上是安装在我的容器.任何想法?
编辑
我尝试了Anthony Tuininga的建议,得到了以下输出:
ODPI [00001] 2023-10-21 19:13:32.206: ODPI-C 5.0.1
ODPI [00001] 2023-10-21 19:13:32.206: debugging messages initialized at level 64
ODPI [00001] 2023-10-21 19:13:32.206: Context Parameters:
ODPI [00001] 2023-10-21 19:13:32.206: Oracle Client Lib Dir: /oracle/instantclient
ODPI [00001] 2023-10-21 19:13:32.206: Environment Variables:
ODPI [00001] 2023-10-21 19:13:32.206: LD_LIBRARY_PATH => "/oracle/instantclient"
ODPI [00001] 2023-10-21 19:13:32.206: load in parameter directory
ODPI [00001] 2023-10-21 19:13:32.206: load in dir /oracle/instantclient
ODPI [00001] 2023-10-21 19:13:32.206: load with name /oracle/instantclient/libclntsh.so
ODPI [00001] 2023-10-21 19:13:32.206: load by OS failure: /oracle/instantclient/libclntsh.so: cannot open shared object file: No such file or directory
ODPI [00001] 2023-10-21 19:13:32.206: load with name /oracle/instantclient/libclntsh.so.19.1
ODPI [00001] 2023-10-21 19:13:32.207: load by OS failure: /oracle/instantclient/libclntsh.so.19.1: cannot open shared object file: No such file or directory
ODPI [00001] 2023-10-21 19:13:32.207: load with name /oracle/instantclient/libclntsh.so.18.1
ODPI [00001] 2023-10-21 19:13:32.207: load by OS failure: /oracle/instantclient/libclntsh.so.18.1: cannot open shared object file: No such file or directory
ODPI [00001] 2023-10-21 19:13:32.207: load with name /oracle/instantclient/libclntsh.so.12.1
ODPI [00001] 2023-10-21 19:13:32.207: load by OS failure: /oracle/instantclient/libclntsh.so.12.1: cannot open shared object file: No such file or directory
ODPI [00001] 2023-10-21 19:13:32.207: load with name /oracle/instantclient/libclntsh.so.11.1
ODPI [00001] 2023-10-21 19:13:32.207: load by OS failure: /oracle/instantclient/libclntsh.so.11.1: cannot open shared object file: No such file or directory
ODPI [00001] 2023-10-21 19:13:32.207: load with name /oracle/instantclient/libclntsh.so.20.1
ODPI [00001] 2023-10-21 19:13:32.207: load by OS failure: /oracle/instantclient/libclntsh.so.20.1: cannot open shared object file: No such file or directory
ODPI [00001] 2023-10-21 19:13:32.207: load with name /oracle/instantclient/libclntsh.so.21.1
ODPI [00001] 2023-10-21 19:13:32.207: load by OS failure: /oracle/instantclient/libclntsh.so.21.1: cannot open shared object file: No such file or directory
Traceback (most recent call last):
File "/app/main.py", line 18, in <module>
['libocci.so.19.1', 'libnnz19.so', 'adrci', 'libipc1.so', 'xstreams.jar', 'libclntsh.so.11.1', 'libclntsh.so.18.1', 'genezi', 'libocci.so.12.1', 'network', 'libocci.so.10.1', 'libocci.so', 'libociei.so', 'libclntsh.so', 'libclntsh.so.12.1', 'libocci.so.18.1', 'libclntsh.so.19.1', 'ucp.jar', 'BASIC_LICENSE', 'libocijdbc19.so', 'ojdbc8.jar', 'BASIC_README', 'libmql1.so', 'liboramysql19.so', 'libocci.so.11.1', 'libclntshcore.so.19.1', 'libclntsh.so.10.1', 'uidrvci']
oracledb.init_oracle_client(os.environ['LD_LIBRARY_PATH'])
File "src/oracledb/impl/thick/utils.pyx", line 476, in oracledb.thick_impl.init_oracle_client
File "src/oracledb/impl/thick/utils.pyx", line 500, in oracledb.thick_impl.init_oracle_client
File "src/oracledb/impl/thick/utils.pyx", line 421, in oracledb.thick_impl._raise_from_info
oracledb.exceptions.DatabaseError: DPI-1047: Cannot locate a 64-bit Oracle Client library: "/oracle/instantclient/libclntsh.so: cannot open shared object file: No such file or directory". See https://python-oracledb.readthedocs.io/en/latest/user_guide/initialization.html for help
型
它表明:
LD_LIBRARY_PATH
正确设置为/oracle/instantclient
- 即时客户端实际上在此目录中搜索
/oracle/instantclient
实际上包含libclntsh.so文件(它实际上是指向libclntsh.so.19.1的符号链接
我觉得很奇怪...
我在这里提供了源代码:https://github.com/galak75/python-oracle-img
编辑2
我尝试使用裸调用init_oracle_client()
,然后它看起来像LD_LIBRARY_PATH
变量没有使用:即时客户端在我的python virtualenv中搜索:
ODPI [00001] 2023-10-22 14:48:34.681: ODPI-C 5.0.1
ODPI [00001] 2023-10-22 14:48:34.681: debugging messages initialized at level 64
ODPI [00001] 2023-10-22 14:48:34.681: Context Parameters:
ODPI [00001] 2023-10-22 14:48:34.681: Environment Variables:
ODPI [00001] 2023-10-22 14:48:34.681: LD_LIBRARY_PATH => "/oracle/instantclient"
ODPI [00001] 2023-10-22 14:48:34.681: check module directory
ODPI [00001] 2023-10-22 14:48:34.681: module name is /app/.venv/lib/python3.12/site-packages/oracledb/thick_impl.cpython-312-aarch64-linux-gnu.so
ODPI [00001] 2023-10-22 14:48:34.681: load in dir /app/.venv/lib/python3.12/site-packages/oracledb
ODPI [00001] 2023-10-22 14:48:34.681: load with name /app/.venv/lib/python3.12/site-packages/oracledb/libclntsh.so
ODPI [00001] 2023-10-22 14:48:34.681: load by OS failure: /app/.venv/lib/python3.12/site-packages/oracledb/libclntsh.so: cannot open shared object file: No such file or directory
ODPI [00001] 2023-10-22 14:48:34.681: load with OS search heuristics
ODPI [00001] 2023-10-22 14:48:34.681: load with name libclntsh.so
ODPI [00001] 2023-10-22 14:48:34.682: load by OS failure: libaio.so.1: cannot open shared object file: No such file or directory
ODPI [00001] 2023-10-22 14:48:34.682: load with name libclntsh.so.19.1
ODPI [00001] 2023-10-22 14:48:34.682: load by OS failure: libaio.so.1: cannot open shared object file: No such file or directory
ODPI [00001] 2023-10-22 14:48:34.682: load with name libclntsh.so.18.1
ODPI [00001] 2023-10-22 14:48:34.682: load by OS failure: libaio.so.1: cannot open shared object file: No such file or directory
ODPI [00001] 2023-10-22 14:48:34.682: load with name libclntsh.so.12.1
ODPI [00001] 2023-10-22 14:48:34.683: load by OS failure: libaio.so.1: cannot open shared object file: No such file or directory
ODPI [00001] 2023-10-22 14:48:34.683: load with name libclntsh.so.11.1
ODPI [00001] 2023-10-22 14:48:34.683: load by OS failure: libaio.so.1: cannot open shared object file: No such file or directory
ODPI [00001] 2023-10-22 14:48:34.683: load with name libclntsh.so.20.1
ODPI [00001] 2023-10-22 14:48:34.683: load by OS failure: libclntsh.so.20.1: cannot open shared object file: No such file or directory
ODPI [00001] 2023-10-22 14:48:34.683: load with name libclntsh.so.21.1
ODPI [00001] 2023-10-22 14:48:34.683: load by OS failure: libclntsh.so.21.1: cannot open shared object file: No such file or directory
ODPI [00001] 2023-10-22 14:48:34.683: check ORACLE_HOME
Traceback (most recent call last):
File "/app/main.py", line 19, in <module>
oracledb.init_oracle_client()
File "src/oracledb/impl/thick/utils.pyx", line 476, in oracledb.thick_impl.init_oracle_client
LD_LIBRARY_PATH = /oracle/instantclient
['libocci.so.19.1', 'libnnz19.so', 'adrci', 'xstreams.jar', 'libclntsh.so.11.1', 'libclntsh.so.18.1', 'genezi', 'libocci.so.12.1', 'network', 'libocci.so.10.1', 'libocci.so', 'libociei.so', 'libclntsh.so', 'libclntsh.so.12.1', 'libocci.so.18.1', 'libclntsh.so.19.1', 'ucp.jar', 'BASIC_LICENSE', 'libocijdbc19.so', 'ojdbc8.jar', 'BASIC_README', 'liboramysql19.so', 'libocci.so.11.1', 'libclntshcore.so.19.1', 'libclntsh.so.10.1', 'uidrvci']
File "src/oracledb/impl/thick/utils.pyx", line 500, in oracledb.thick_impl.init_oracle_client
File "src/oracledb/impl/thick/utils.pyx", line 421, in oracledb.thick_impl._raise_from_info
oracledb.exceptions.DatabaseError: DPI-1047: Cannot locate a 64-bit Oracle Client library: "libaio.so.1: cannot open shared object file: No such file or directory". See https://python-oracledb.readthedocs.io/en/latest/user_guide/initialization.html for help
型
编辑3
我在代码中添加了libaio1
软件包安装,因为正如Christopher's answer所指出的,这显然是下一个问题(在目标OS平台问题之后
3条答案
按热度按时间5cg8jx4n1#
如果你不需要厚模式,你可以通过简单地删除对
init_oracle_client()
的调用来完全避免错误。如果您确实需要它,因为在精简模式下的限制,在运行脚本之前将环境变量
DPI_DEBUG_LEVEL
设置为值64。这可能有助于您诊断问题。如果不是,请将输出包含在您的问题中,我会查看。[更新:通过提供的输出,很明显,aio库丢失了,Chris在他的回答中也提出了这一点。添加该库,您的问题应该消失!]
使用
os.listdir(os.environ["LD_LIBRARY_PATH"])
列出在目录中找到的文件也可能很有帮助。注意,在Linux上不能指定库目录,因此必须使用对
init_oracle_client()
的裸调用。huus2vyu2#
有关参考,请参见Docker for Oracle Database Applications in Node.js and Python。
当我尝试你的Dockerfile时,我得到了一个相当明确的消息,libaio包没有安装。
下一个问题(除了丢失的锁文件!)是main.py正在为连接使用上下文管理器,但也显式关闭了连接。
这个Dockerfile适合我:
字符串
注意,我删除了重载使用的ORACLE_HOME,因为这在Oracle中有特定的含义。我也直接使用了python,因为容器可能只运行一个应用程序环境。
我也更喜欢ldconfig而不是LD_LIBRARY_PATH,因为后者容易出现各种问题。
main.py
是:型
遵循Anthony的建议,不要在Linux上将
lib_dir
传递给init_oracle_client()
。输出类似于:
型
最后,您应该重新访问在容器中运行的用户。
taor4pac3#
我终于想通了,经过这么多个小时的挣扎!
我正在一台带有M1芯片(
arm64
架构)的MacBook上运行,同时我正在为amd64
架构安装一个instantclient发行版。然后我通过强制目标Docker平台为
amd64
来实现它:字符串
注意:我还必须修复一些问题,例如安装
libaio1
debian包,并删除conn.close()
python语句**编辑:**另一种解决方案是根据目标操作系统平台下载正确的即时客户端包:
型