2

I am getting the following error.

cx_Oracle.DatabaseError: DPI-1047: 64-bit Oracle Client library cannot be loaded: "dlopen(libclntsh.dylib, 1): image not found".

One fix that I found was to insert cx_Oracle.init_oracle_client(lib_dir=path) which lead to a Oracle Client Library has already been initialized Error.

However I do not call init_oracle_client anywhere in the code. I am using Python 3.8.11 and cx_Oracle 8.2.1 on a Mac.

When I initially ran the code, I did not have any Oracle Client installed. I then downloaded instantclient_19_8, but using that with init_oracle_client lead to the already initialized error. I saw this here https://cx-oracle.readthedocs.io/en/latest/user_guide/initialization.html.

I am not sure where the cx_Oracle binary is, when I go to the location that has my current anaconda environment, I see a cx_Oracle-doc folder that has readme files. In addition, an oradiag_my_username folder has been created in ~. Not sure what needs to be fixed.

Christopher Jones
  • 9,449
  • 3
  • 24
  • 48
Ashwin
  • 323
  • 2
  • 4
  • 16
  • can you show the code ? – Roberto Hernandez Sep 13 '21 at 15:47
  • Is there any connection with the code? Right now the error is at a call of ```cx_Oracle.connect(username,password,dsn)``` – Ashwin Sep 13 '21 at 15:52
  • Try the answer to [this similar question](https://stackoverflow.com/questions/53098434/64-bit-oracle-client-library-cannot-be-loaded-in-mac) and see if it solves your issue. – kfinity Sep 13 '21 at 16:41
  • Probably not as the commentators indicated that it would work for older versions. Make sure you are not using the bundled Python. - This seems to be the first instruction. How do you check that.? I can confirm that the version of Python I have is not the same as that in the base environment. – Ashwin Sep 13 '21 at 17:33

1 Answers1

7

The easiest solution now would be to use the latest cx_Oracle version, which was renamed to python-oracledb, see the release announcement. This doesn't need Oracle Client libraries (they are optional).

If you use cx_Oracle (or the Thick mode of python-oracledb), you can use something like this:

import os
import platform
if platform.system() == "Darwin":
    cx_Oracle.init_oracle_client(lib_dir=os.environ.get("HOME")+"/Downloads/instantclient_19_8")

This is the most convenient solution. If you are getting an 'already initialized' error, then make sure you only call init_oracle_client() once per Python process if you are using cx_Oracle 8. If you are using the new version (renamed to python-oracledb), then you can call init_oracle_client() multiple times as long as the arguments are the same.

Alternatively you can find your cx_Oracle binary like:

cjones@mac:~$ python
Python 3.9.6 (default, Aug 20 2021, 13:36:17) 
[Clang 12.0.5 (clang-1205.0.22.11)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import cx_Oracle
>>> cx_Oracle
<module 'cx_Oracle' from '/Users/cjones/.local/lib/python3.9/site-packages/cx_Oracle.cpython-39-darwin.so'>

and then, in a terminal window, do something like:

ln -s $HOME/Downloads/instantclient_19_8/libclntsh.dylib $HOME/.local/lib/python3.9/site-packages

This is for macOS - any Linux users reading this should be aware this solution won't work on Linux.

The oradiag_xxx directory is for Oracle "client" traces. You can delete this at anytime.

Christopher Jones
  • 9,449
  • 3
  • 24
  • 48
  • Spent way too much on trying see where else init_oracle_client() was called. Surprisingly still had the error. The symlinks method worked well. Thanks for the oradiag tip, wasn't sure where that folder mysteriously came up from. – Ashwin Sep 14 '21 at 16:06