首页 > 解决方案 > Docker python 使用 ODPI-C 进行 Oracle 数据库连接

问题描述

我是 Docker 的新手,我尝试了一个包含要测试的 python 应用程序的构建映像。此应用程序必须连接到 Oracle 数据库。

我尝试使用此 Dockerfile 进行构建

FROM python:3.6.4

COPY . /app
WORKDIR /app

RUN pip install --upgrade pip
RUN pip install pystan
RUN pip install cx_Oracle
RUN pip install -r requirements.txt

CMD [ "python", "Main.py" ]

并运行图像。我收到以下错误

Traceback (most recent call last):
  File "Main.py", line 24, in <module>
    branch_config_main = Utility.return_branch_config(engine)
  File "/app/Utility.py", line 18, in return_branch_config
    branch_config = pd.read_sql_query('SELECT t1.* , t2.CO_BANK FROM tbpr_strategy_param t1 INNER JOIN tbpr_location_info t2 ON t1.LOCATION_ID = t2.LOCATION_ID', con = engine)
  File "/usr/local/lib/python3.6/site-packages/pandas/io/sql.py", line 314, in read_sql_query
    parse_dates=parse_dates, chunksize=chunksize)
  File "/usr/local/lib/python3.6/site-packages/pandas/io/sql.py", line 1098, in read_query
    result = self.execute(*args)
  File "/usr/local/lib/python3.6/site-packages/pandas/io/sql.py", line 989, in execute
    return self.connectable.execute(*args, **kwargs)
  File "/usr/local/lib/python3.6/site-packages/sqlalchemy/engine/base.py", line 2165, in execute
    connection = self._contextual_connect(close_with_result=True)
  File "/usr/local/lib/python3.6/site-packages/sqlalchemy/engine/base.py", line 2226, in _contextual_connect
    self._wrap_pool_connect(self.pool.connect, None),
  File "/usr/local/lib/python3.6/site-packages/sqlalchemy/engine/base.py", line 2266, in _wrap_pool_connect
    e, dialect, self
  File "/usr/local/lib/python3.6/site-packages/sqlalchemy/engine/base.py", line 1536, in _handle_dbapi_exception_noconnection
    util.raise_from_cause(sqlalchemy_exception, exc_info)
  File "/usr/local/lib/python3.6/site-packages/sqlalchemy/util/compat.py", line 399, in raise_from_cause
    reraise(type(exception), exception, tb=exc_tb, cause=cause)
  File "/usr/local/lib/python3.6/site-packages/sqlalchemy/util/compat.py", line 153, in reraise
    raise value.with_traceback(tb)
  File "/usr/local/lib/python3.6/site-packages/sqlalchemy/engine/base.py", line 2262, in _wrap_pool_connect
    return fn()
  File "/usr/local/lib/python3.6/site-packages/sqlalchemy/pool/base.py", line 363, in connect
    return _ConnectionFairy._checkout(self)
  File "/usr/local/lib/python3.6/site-packages/sqlalchemy/pool/base.py", line 760, in _checkout
    fairy = _ConnectionRecord.checkout(pool)
  File "/usr/local/lib/python3.6/site-packages/sqlalchemy/pool/base.py", line 492, in checkout
    rec = pool._do_get()
  File "/usr/local/lib/python3.6/site-packages/sqlalchemy/pool/impl.py", line 139, in _do_get
    self._dec_overflow()
  File "/usr/local/lib/python3.6/site-packages/sqlalchemy/util/langhelpers.py", line 68, in __exit__
    compat.reraise(exc_type, exc_value, exc_tb)
  File "/usr/local/lib/python3.6/site-packages/sqlalchemy/util/compat.py", line 154, in reraise
    raise value
  File "/usr/local/lib/python3.6/site-packages/sqlalchemy/pool/impl.py", line 136, in _do_get
    return self._create_connection()
  File "/usr/local/lib/python3.6/site-packages/sqlalchemy/pool/base.py", line 308, in _create_connection
    return _ConnectionRecord(self)
  File "/usr/local/lib/python3.6/site-packages/sqlalchemy/pool/base.py", line 437, in __init__
    self.__connect(first_connect_check=True)
  File "/usr/local/lib/python3.6/site-packages/sqlalchemy/pool/base.py", line 639, in __connect
    connection = pool._invoke_creator(self)
  File "/usr/local/lib/python3.6/site-packages/sqlalchemy/engine/strategies.py", line 114, in connect
    return dialect.connect(*cargs, **cparams)
  File "/usr/local/lib/python3.6/site-packages/sqlalchemy/engine/default.py", line 451, in connect
    return self.dbapi.connect(*cargs, **cparams)
sqlalchemy.exc.DatabaseError: (cx_Oracle.DatabaseError) DPI-1047: Cannot locate a 64-bit Oracle Client library: "libclntsh.so: cannot open shared object file: No such file or directory". See https://oracle.github.io/odpi/doc/installation.html#linux for help
(Background on this error at: http://sqlalche.me/e/4xp6)

所以我按照链接https://oracle.github.io/odpi/doc/installation.html中的指南并使用多阶段构建以下列方式修改 Dockerfile

FROM oraclelinux:7-slim

ARG release=19
ARG update=3

RUN  yum -y install oracle-release-el7 && yum-config-manager --enable ol7_oracle_instantclient && \
     yum -y install oracle-instantclient${release}.${update}-basic oracle-instantclient${release}.${update}-devel oracle-instantclient${release}.${update}-sqlplus && \
     rm -rf /var/cache/yum

CMD ["sqlplus", "-v"]

FROM python:3.6.4

COPY . /app
WORKDIR /app

RUN pip install --upgrade pip
RUN pip install pystan
RUN pip install cx_Oracle
RUN pip install -r requirements.txt

CMD [ "python", "Main.py" ]

但我总是得到同样的错误。我在哪里做错了?在这一点上,我正在浪费很多时间。

更新

当我尝试运行容器时,我看到在服务器中安装了 Oracle 即时客户端 18.5。但是尽管设置了环境变量 ENV LD_LIBRARY_PATH=/opt/oracle/instantclient_18_5/libclntsh.so 我总是得到同样的错误。我还尝试了 Christopher Jones 建议的解决方案,替换了 oraclelinux:7-slim 构建的第一部分,但没有帮助。

这是安装 Oracle 即时客户端的目录

Oracle 即时客户端 18.5

标签: pythonoracledockerdockerfiledatabase-connection

解决方案


我解决了这个问题。通过多阶段构建,我丢失了重要信息,因此我使用 Christopher 的解决方案提议者将所有内容放在一个构建中。

这是新的 Dockerfile

FROM python:3.6.4

RUN apt-get update && apt-get install -y libaio1 wget unzip

WORKDIR /opt/oracle 
RUN wget https://download.oracle.com/otn_software/linux/instantclient/instantclient- 
basiclite-linuxx64.zip && \ unzip instantclient-basiclite-linuxx64.zip && rm 
-f instantclient-basiclite-linuxx64.zip && \ cd /opt/oracle/instantclient* 
&& rm -f jdbc occi mysql *README jar uidrvci genezi adrci && \ echo 
/opt/oracle/instantclient > /etc/ld.so.conf.d/oracle-instantclient.conf && 
ldconfig 
RUN pip install --upgrade pip

COPY . /app 
WORKDIR /app

RUN pip install --upgrade pip 
RUN pip install pystan 
RUN apt-get -y update && python3 -m pip install cx_Oracle --upgrade 
RUN pip install -r requirements.txt

CMD [ "python", "Main.py" ]

现在一切正常!谢谢大家!


推荐阅读