Home > Enterprise >  How to identify Oracle Instant Client in a Django project?
How to identify Oracle Instant Client in a Django project?

Time:06-17

I try to link an external Oracle database on which I have read-only privileges to my Django project and then only send it raw SQL queries.

So I first created a second table in my project settings (because I still need the default database)

settings.py

DATABASES = {
'default': {
    'ENGINE': 'django.db.backends.sqlite3',
    'NAME': BASE_DIR / 'db.sqlite3',
},
'oracleDB':{
    'ENGINE': 'django.db.backends.oracle',
    'NAME': 'my_dsn',
    'USER': 'my_user',
    'PASSWORD': 'my_password',
    'HOST': 'my_host',
    'PORT': 'my_port',
    'OPTIONS':{
        'threaded':True
    }
}

Then in my view I call it this way (seen on a forum):

views.py

from django.db import connections
def my_function(request):
    with connections['oracleDB'].cursor() as cur:
        cur.execute( "SOME SQL QUERY")
        print(cur.fetchall())

And I get this error

DPI-1047: Cannot locate a 64-bit Oracle Client library: “C: ProgramData Oracle12c product 12.1.0 client_1 bin oci.dll is not the correct architecture”. See cx_Oracle 8 Installation — cx_Oracle 8.3.0 documentation for help

I know that I need the Oracle instantclient to connect, I used to use it in connection with the cx_Oracle package and it worked well (so i'm certain the version is good). Except that now I connect with Django and its settings where I can’t specify the path to my Oracle instantclient.

Do you have any idea how to enable Django to detect this client?

I am under Windows 10 64bits.

Thank you in advance, please feel free to ask me to develop

CodePudding user response:

  • It seems that you might have multiple versions of Oracle libraries installed. As you found, you need to make sure that a 64-bit set of Oracle Client libraries is available to Python. Or alternatively use a 32-bit Python executable.

  • If you already have the libraries installed on this machine (since you say you can use cx_Oracle directly), then in your Django settings.py file add a call to cx_Oracle.init_oracle_client(lib_dir=r"\path\to\instantclient"). (This technique also works on macOS, but not Linux)

  • Alternatively, use the new major version of cx_Oracle - which got renamed to python-oracledb, see the release announcement. It doesn't need Oracle Client libraries. See this post.

CodePudding user response:

It’s okay I solved my problem by adding:

settings.py

import cx_Oracle
cx_Oracle.init_oracle_client(lib_dir="my_path_to_oracle_client")
 
DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.sqlite3',
            'NAME': BASE_DIR / 'db.sqlite3',
        },
        'oracleDB':{
            'ENGINE':'django.db.backends.oracle',
            'NAME':(
                '(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=my_host)(PORT=my_port))'
                '(CONNECT_DATA=(SERVICE_NAME=my_service)))'
            ),
            'USER':'my_user',
            'PASSWORD':'my_password',
        }

So I added client initialization by cx_Oracle directly in Django’s settings and I modified my NAME that didn’t allow recognition of the database before that.

For the query of the base then I do like this:

views.py

from django.db import connections
 
with connections['oracleDB'].cursor() as cur:
        cur.execute("""MY_SQL_QUERY""")
  • Related