With the python-oracledb driver the code:
import oracledb
cs = "MYDB"
c = oracledb.connect(user='cj', password=mypw, dsn=cs)
gives the error:
oracledb.exceptions.DatabaseError: DPY-4027: no configuration directory to search for tnsnames.ora
The same error also occurs in a second case:
import oracledb
cs = "MYDB = (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=localhost)(PORT=1521))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=orclpdb1)))"
c = oracledb.connect(user='cj', password=mypw, dsn=cs)
and with this:
import oracledb
cs = "MYDB = (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=localhost)(PORT=1521))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=orclpdb1)))"
cp = oracledb.ConnectParams()
cp.parse_connect_string(cs)
What does this mean?
This error means you used a connection string that python-oracledb took to be some kind of alias it needed to look up in a tnsnames.ora
file, but it didn't know where to find that file. You need to either tell python-oracledb where to find the file, or use a different connection string syntax.
Database connection strings in python-oracledb are commonly one of:
An Oracle Easy Connect string like myhost:1521/orclpdb1
An Oracle Net Connect Descriptor string like (DESCRIPTION=(ADDRESS=(...))
A TNS alias mapping to a connect descriptor. These connect descriptors are commonly stored in a tnsnames.ora
configuration file on the machine where you are running Python. The file maps the alias to a connect descriptor that really tells Oracle where the database is located, . The tnsnames.ora
file might look like:
MYDB =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = 0.0.0.0)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = ORCLPDB1)
)
)
Your Python code to use this might be like:
c = oracledb.connect(user='cj', password=mypw, dsn="MYDB")
See the connection string documentation.
It is generally your choice about which connection string syntax to use.
Solutions to DPY-4027
One option is to change to the equivalent Easy Connect syntax, and not use a tnsnames.ora
file:
c = oracledb.connect(user='cj', password=mypw,
dsn="localhost:1521/orclpdb1")
If you do use a tnsnames.ora
file, python-oracledb has some heuristics to automatically locate the file. E.g using the TNS_NAMES
or ORACLE_HOME
environment variables, or via a default location. Refer to the documentation on defaults and make sure your file is in the correct location, and any environment variable is set for the Python process. (Note these heuristics were improved / changed in python-oracledb 3.0).
If you are having problems with the heuristics, you can explicitly tell python-oracledb where your tnsnames.ora
is. For example, if you have /opt/myconfigdir/tnsnames.ora
, then:
In python-oracledb's default 'Thin' mode, use:
c = oracledb.connect(user='cj', password=mypw, dsn="MYDB",
config_dir='/opt/myconfigdir')
In python-oracledb's Thick mode (which is the mode when the app calls init_oracle_client()
) then use:
oracledb.init_oracle_client(config_dir='/opt/myconfigdir')
c = oracledb.connect(user='cj', password=mypw, dsn="MYDB")