用python-oracledb做什么'DPY-4027:没有配置目录可供搜索tnsname.ora'意思是

qmelpv7a  于 2022-11-03  发布在  Oracle
关注(0)|答案(1)|浏览(481)

1.对于python-oracledb驱动程序,代码:

import oracledb

cs = "MYDB"
c = oracledb.connect(user='cj', password=mypw, dsn=cs)

给出错误:

oracledb.exceptions.DatabaseError: DPY-4027: no configuration directory to search for tnsnames.ora

1.在第二种情况下也会发生相同的错误:

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)

和这个:

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)

这是什么意思呢?

mwngjboj

mwngjboj1#

这个错误意味着您使用了一个连接字符串,python-oracledb将其当作某种别名,需要在tnsnames.ora文件中查找,但它不知道在哪里可以找到该文件。
python-oracledb中的数据库连接字符串可以是以下字符串之一:

  • 类似myhost:1521/orclpdb1的Oracle轻松连接字符串
  • Oracle Net连接描述符字符串,如(DESCRIPTION=(ADDRESS=(...))
  • Map到连接描述符的网络服务名别名

请参阅有关连接字符串的用户文档
如果连接字符串是别名,或者未被识别为轻松连接字符串或连接描述符,则必须具有将别名Map到连接描述符的tnsnames.ora配置文件。tnsnames.ora文件可能如下所示:

MYDB = (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=localhost)(PORT=1521))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=orclpdb1)))

案例1

import oracledb

cs = "MYDB"
c = oracledb.connect(user='cj', password=mypw, dsn=cs)

要使用这个连接字符串,需要告诉python-oracledb在哪里可以找到tnsnames.ora文件,该文件包含从别名MYDB到连接描述符的Map,该描述符实际上告诉Oracle数据库的位置。(请参阅this answer了解原因)。
如果您有一个/opt/myconfigdir/tnsnames.ora文件,那么在python-oracledb的默认“精简”模式下,您可以执行以下操作:

import oracledb

cs = "MYDB"
c = oracledb.connect(user='cj', password=mypw, dsn=cs, config_dir='/opt/myconfigdir')

请注意,即使设置了ORACLE_HOME,精简模式也不会自动读取$ORACLE_HOME/network/admin/tnsnames.ora。您必须明确告诉python-oracledb(在精简模式下)从何处读取文件。
在Thick模式下(应用程序调用init_oracle_client()时的模式),如果tnsnames.ora文件 * 没有 * 放在默认位置,那么您可以告诉python-oracledb在哪里找到它,如下所示:

import oracledb

oracledb.init_oracle_client(config_dir='/opt/myconfigdir')

cs = "MYDB"
c = oracledb.connect(user='cj', password=mypw, dsn=cs)

在这两种模式下,你都可以将环境变量TNS_ADMIN设置为包含文件的目录,然后运行Python。

案例2:

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)

这是纯粹的“输入错误”。作为连接字符串传递的是一个字符串,它包含 * 同时 * 网络服务名别名和连接描述符,这是tnsnames.ora配置文件中使用的语法,而不是应用程序本身。
Python-oracledb不理解此语法,并假定您正在尝试传递网络服务名别名。它需要在tnsnames.ora文件中查找此别名,但无法找到这样的文件。
一种解决方案是只传递连接描述符组件,而不传递MYDB =部分。例如:

import oracledb

cs = "(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=localhost)(PORT=1521))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=orclpdb1)))"
c = oracledb.connect(user='cj', password=mypw, dsn=cs)

或者,您可以将原始的整个字符串放入一个tnsnames.ora文件中,然后调用:

import oracledb

cs = "MYDB"
c = oracledb.connect(user='cj', password=mypw, dsn=cs)

请参阅上面的示例,了解文件的位置。
另一种方法是使用Easy Connect语法:

import oracledb

cs = "localhost:1521/orclpdb1"
c = oracledb.connect(user='cj', password=mypw, dsn=cs)

相关问题