In my local machine
I have created a script in python that retrieves data from an Oracle database.
The connection to the DB is done using cx_Oracle:
con = cx_Oracle.connect (username, password, dbService)
When using SQL developer the connection is established using custom JDBC.
Replicate procedure on a Linux server.
I have created a python virtual environment with cx-Oracle pip installed in it.
I have Oracle Client 19.3.0 installed in the server, and the folder instantclient is in place.
When I try to execute the python script as is I get the following error.
cx_Oracle.DatabaseError: DPI-1047: Cannot locate a 64-bit Oracle
Client library:
DPI-1047: Cannot locate a 64-bit Oracle Client library: "libclntsh.so: cannot open shared object file: No such file or directory". See https://cx-oracle.readthedocs.io/en/latest/user_guide/installation.html for help
I assumed that the problem was the Oracle path which is not the one that python expected. So, I added this extra line of code pin-pointing the path where the Oracle libraries are located.
cx_Oracle.init_oracle_client(lib_dir=r"/apps/oracle/product/19.3.0/lib")
This leads to a different error:
cx_Oracle.DatabaseError: Error while trying to retrieve text for error
ORA-01804
Any clues?
The answer to my question was indicated by the ORA-1804 message.
According to the Oracle initialization doc: https://cx-oracle.readthedocs.io/en/latest/user_guide/initialization.html#usinginitoracleclient
Note if you set lib_dir on Linux and related platforms, you must still
have configured the system library search path to include that
directory before starting Python.
On any operating system, if you set
lib_dir to the library directory of a full database or full client
installation, you will need to have previously set the Oracle
environment, for example by setting the ORACLE_HOME environment
variable. Otherwise you will get errors like ORA-1804. You should set
this, and other Oracle environment variables, before starting Python,
as shown in Oracle
Even though defining the ORACLE_HOME should be done before starting Python (according to Oracle documentation) it is possible to do so by modifying the python script itself. So before the oracle client initialization command the following commands had to be added:
import os
# Setup Oracle paths
os.environ["ORACLE_HOME"] = '/apps/oracle/product/19.3.0'
os.environ["ORACLE_BASE"] = '/apps/oracle'
os.environ["ORACLE_SID"] = 'orcl'
os.environ["LD_LIBRARY_PATH"] = '/apps/oracle/product/19.3.0/lib'
import cx_Oracle
# Initialize Oracle client
cx_Oracle.init_oracle_client(lib_dir=r"/apps/oracle/product/19.3.0/lib")
The cx_Oracle initialization doc points out that on Linux init_oracle_client() doesn't really do what you think it does. You must still set the system library search path to include the Oracle libraries before the Python process starts.
Do I understand correctly that the machine with Python has both the DB installed and Instant Client??
If you do want Python to use the Instant Client libraries, then set LD_LIBRARY_PATH to its location and do not set ORACLE_HOME.
If you have a full Oracle DB installation on the machine with Python, then you can delete Instant Client. You need to set ORACLE_HOME, LD_LIBRARY_PATH and whatever else is needed before starting Python - in general run source /usr/local/bin/oraenv. This should set the system library search path to include /apps/oracle/product/19.3.0/lib . A code snippet like this (untested) one may help: export ORACLE_SID=ORCLCDB;set ORAENV_ASK=NO; source /usr/local/bin/oraenv. Make sure the Python process has read access to the ORACLE_HOME directory.
The cx_Oracle installation guide discusses all this.
Related
I have a problem that I've been trying to solve for a very long time and it seems like I'm missing something very basic.
I use a Linux server with Anaconda, Oracle client, Pycharm and jupyter-notebook installed.
I use python scripts in which I write and read data to Oracle DB, and I use the Cx_oracle extension.
The server has several users with a personal username for each and each of them has sudo privileges.
I performed all the installations on the server with sudo privileges.
When I try to connect from the server to Oracle DB I connect properly.
When I connect to Python on the server itself, I connect properly to Oracle DB.
When I connect using Pycharm and I define ORACLE_HOME=/OracleTools/19.0.0/ in the environment variables, I connect properly to the Oracle DB.
My problem starts when I want to use jupyter-notebook
When I try to connect to the DB I get the error -
DatabaseError: Error while trying to retrieve text for error ORA-12715
I noticed when I execute os.environ I see that it is defined for me:
ORACLE_HOME: /OracleTools/19.0.0/bin
and should be
/OracleTools/19.0.0
So I changed using command os.environ['ORACLE_HOME'] = '/OracleTools/19.0.0'
Then I get an error:
DatabaseError: ORA-12715: invalid character set specified
And of course this change is not permanently saved ...
If on the server itself I execute the env command both in the private user and in sudo I see ORACLE_HOME: /OracleTools/19.0.0 and not ORACLE_HOME: /OracleTools/19.0.0/bin
My questions:
Where does the data I get in the os.environ command come from?
How can I edit them permanently ?
Is this even the problem I'm having or should I check something else?
I manage to import cx_oracle, which means that there is no problem of expansion
Thanks!
I try to connect oracle DB with cx_Oracle package in python 3.9.7.
cx_Oracle version is 8.3.0.
when i try to connect with command cx_Oracle.clientversion() i got error :
DatabaseError: Error while trying to retrieve text for error ORA-01804
Linux Os , attach my .bash_profile
with sqlplus command i success to connect the DB.
.bash_profile :
Thanks
This error generally occurs when there is a discrepancy between the value of the environment variable ORACLE_HOME and the actual library that was loaded. You can set the environment variable DPI_DEBUG_LEVEL to the value 64 and run your script. It will tell you which method was used to load the library. If that doesn't help you figure it out, paste the output in your question and I'll try to help further.
Note as well that there is a new driver available (python-oracledb) which doesn't require Oracle Client libraries and therefore shouldn't run into this issue. Take a look here: https://levelup.gitconnected.com/open-source-python-thin-driver-for-oracle-database-e82aac7ecf5a
I am connecting to an Oracle DB using LDAP and the Python cx_Oracle library. I have proper sqlnet.ora, ldap.ora and tnsnames.ora files. On my Windows machine everything works fine using the 12.1 Oracle client and the following Python code:
import cx_Oracle
connection = cx_Oracle.connect(user/password#db, mode=cx_Oracle.SYSDBA)
I have installed the Oracle instant client 12.1 on my Linux machine (Debian) following the zip file installation method advised on the Oracle website (at the bottom of https://www.oracle.com/be/database/technologies/instant-client/linux-x86-64-downloads.html).
ldconfig correctly lists the oracle client libraries and their paths.
I copy the exact same sqlnet.ora, ldap.ora and tnsnames.ora files from my Windows machine to my Linux machine
in /opt/oracle/instantclient_12_1/network/admin, as advised by the cx_Oracle documentation.
Now running the above Python code on my Linux machine I have the following error:
cx_Oracle.DatabaseError: ORA-12154: TNS:could not resolve the connect identifier specified
I tried as well setting the environment variable TNS_ADMIN=/opt/oracle/instantclient_12_1/network/admin and ORACLE_HOME=/opt/oracle/instantclient_12_1/ with no success neither
Could any of you help me debugging this and understand why the client config on my Linux machine does not work?
Installed the latest 19 client and everything works as expected.
I'm trying to use QOCI driver to connect to Oracle Database, but the driver is not available. For this simple code:
from PyQt5 import QtSql
QtSql.QSqlDatabase.isDriverAvailable('QOCI')
I get False.
I tried checking the PATH environmental settings, and I see that there is TNS_ADMIN variable set to folder with driver file oci.dll:
C:\Atena\instantclient_11_2
but it's still unavailable.
I tried downloading the driver from Oracle site, setting it up according to Oracle instructions (changing the PATH variable to the new driver folder, copying TNSnames.ora file etc.), but still the driver is unavailable.
I want to have the driver available for PyQt5, load it, and the use it to connect to Oracle database.
The OCI.DLL is included for example in instantclient-basic-windowsXXXXX.zip
Assume you have unzipped file to
C:\ORACLE\IC\12201\instantclient_12_2
to make it available for other applications, set in user environment
ORACLE_HOME=C:\ORACLE\IC\12201\instantclient_12_2
PATH=%PATH%;%ORACLE_HOME%
with this setting any application using OCI.DLL should find it.
Of course you have to install the right bitsize - i.e. if you application is 32bit, you need to install a 32bit Instant Client - if it is a 64bit App, you need 64bit instant client.
So - as far as I can see you need to build the QOCI manually. To do that, you need definetly the SDK package for instant client.
Sources on the web state that you need to include headers and libs from SDK - unfortunatly it looks like the QOCI still depends on Oracle Client 11.X - not instant client but regular client.
following libraries need to be used (last one is for client 12.x)
oci.lib ociw32.lib oraocci12.lib
on regular client
%ORACLE_HOME%\oci\lib\msvc
on instant client
%ORACLE_HOME%\sdk\lib\msvc
following headers need to be included
oci.h
on regular client
%ORACLE_HOME%\oci\include
on instant client
%ORACLE_HOME%\sdk\include
Unfortunatly there is no much support for MinGW so I cannot do that.
the "configure" command to prepare everything needs to include
-sql-oci -plugin-sql-oci
I'm trying to install MYSQLdb on a windows client. The goal is, from the Windows client, run a python script that connects to a MySQL server on a LINUX client. Looking at the setup code (and based on the errors I am getting when I try to run setup.py for mysqldb, it appears that I have to have my own version of MySQL on the windows box. Is there a way (perhaps another module) that will let me accomplish this? I need to have people on multiple boxes run a script that will interact with a MySQL database on a central server.
you could use a pure python implementation of the mysql client like
pymysql
(can be used as a dropin-replacement for MySQLdb by calling pymysql.install_as_MySQLdb())
MySql-Connector
You don't need the entire MySQL database server, only the MySQL client libraries.
It's been a long time since I wrote python db code for windows...but I think something like this should still work.
If you're running the client only on windows machines, install the pywin32 package. This should have an odbc module in it.
Using the windows control / management tools, create an odbc entry for either the user or the system. In that entry, you'll give the connection parameter set a unique name, then select the driver (in this case MySQL), and populate the connection parameters (e.g. host name, etc.) See PyWin32 Documentation for some notes on the odbc module in pywin32.
Also, see this post: Common ways to connect to odbc from python on windows.