Search code examples
djangooracledockerinstantclient

cx_Oracle DatabaseError: DPI-1047


I'm trying to run my Django application in Docker, but I'm getting an error: cx_Oracle.DatabaseError: DPI-1047: Cannot locate a 64-bit Oracle Client library: "/root/lib/oracle/instantclient_23_4/libclntsh.so: cannot open shared object file: No such file or directory"

The application itself runs on PostgreSQL, but also has a connection to Oracle

OS: Ubuntu Server

I installed instantclient, and created an env variable via ~/.bashrc using the command: export LD_LIBRARY_PATH=/root/lib/oracle/instantclient_23_4:$LD_LIBRARY_PATH, and added an initialization line in the python file: cx_Oracle.init_oracle_client(lib_dir="root/lib/oracle/instantclient_23_4"), but I still get the above error.

If I run the file directly: python3 omega_db.py, the script works fine and shows the database connection, but if I run it through docker-compose up, I get the error.

instantclient


Solution

  • The easiest solution is to use the latest version of cx_Oracle. It was renamed python-oracledb and doesn't need Instant Client, see the release announcement. Install with:

    $ python3 -m pip install oracledb
    

    Then change your code following Steps to Upgrade to python-oracledb and, in your case, removing all calls to init_oracle_client() so you don't invoke Instant Client.

    If you are using Django 5, you are good to go: see Django 5.0 supports python-oracledb natively. If you are still using an older version then see Using python-oracledb 1.0 with SQLAlchemy, Pandas, Django and Flask and add those few extra lines to your settings file:

    import sys
    import oracledb
    oracledb.version = "8.3.0"
    sys.modules["cx_Oracle"] = oracledb
    

    If you must use cx_Oracle, then follow best practices for library path configuration and use ldconfig instead of setting LD_LIBRARY_PATH. It sounds like you are setting the variable in the wrong layer. Read Docker for Oracle Database Applications in Node.js and Python.

    Try this in the layer where Python will run:

    $ echo /root/lib/oracle/instantclient_23_4 > /etc/ld.so.conf.d/oic.conf
    $ ldconfig