このような接続文字列があります
con_str = "myuser/[email protected]:1521/ora1"
ここで、ora1
はデータベースのSIDです。 SQL Developerでこの情報を使用すると正常に機能します。つまり、問題なく接続してクエリを実行できます。
ただし、この文字列を使用してOracleに接続しようとすると失敗します。
cx_Oracle.connect(con_str)
DatabaseError: ORA-12514: TNS:listener does not currently know of service requested in connect descriptor
ただし、ora1
がサービス名の場合、この接続文字列形式は機能します。
私は私の問題の逆を持っているように見える他の質問を見ました(それはSIDで動作しますが、サービス名では動作しません)
cx_Oracle
を使用し、サービス名ではなくSID
を使用してOracleに接続する適切な方法は何ですか? TNSNAMES.ORA
ファイルを調整せずにこれを行うにはどうすればよいですか?私のアプリケーションは内部で多くのユーザーに配布されており、TNSNAMES
ファイルに変更を加えることは、Windowsマシンの管理者権限のないユーザーを扱う場合には理想的ではありません。さらに、サービス名を使用する場合、このファイルにまったく触れる必要はなく、そのままにしておく必要があります。
同様のシナリオで、 cx_Oracle.makedsn()
を使用してデータベースに接続し、dsn文字列を作成できました。 (サービス名の代わりに)SID
を指定:
_dsnStr = cx_Oracle.makedsn("Oracle.sub.example.com", "1521", "ora1")
_
これは次のようなものを返します
_(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(Host=Oracle.sub.example.com)(PORT=1521)))(CONNECT_DATA=(SID=ora1)))
_
その後、 cx_Oracle.connect()
を使用してデータベースに接続できます。
_con = cx_Oracle.connect(user="myuser", password="mypass", dsn=dsnStr)
print con.version
con.close()
_
SIDの代わりにservice_nameを指定する方法を探している人向け。
SQLAlchemy 1.0.0b1の changelog から(2015年3月13日にリリース):
[Oracle] [機能]
?service_name=<name>
をURLに渡すことにより、tns名ではなく、特定のサービス名へのcx_Oracle接続のサポートを追加しました。プルリクエスト(SławomirEhlert提供).
この変更により、新しいOracle方言固有のオプションservice_name
が導入されました。これは、次のような接続文字列の構築に使用できます。
from sqlalchemy import create_engine
from sqlalchemy.engine import url
connect_url = url.URL(
'Oracle+cx_Oracle',
username='some_username',
password='some_password',
Host='some_Host',
port='some_port',
query=dict(service_name='some_Oracle_service_name'))
engine = create_engine(connect_url)
SqlalchemyとOracle 12を使用している場合、次のように動作するようです。
from sqlalchemy import create_engine
con='Oracle://user:password@hostname:1521/?service_name=DDDD'
engine = create_engine(con)
SIDではなく、サービス名を使用する必要があることに注意してください。理由はわかりませんが、SIDを使用する単純な接続文字列は機能しません。
SIDは簡単にアクセスできない場合や、データベース用に作成されていない場合があります。
私の場合、クライアント側からクラウドデータベースへのアクセスをリクエストしているので、SIDを作成するのはあまり意味がありません。
代わりに、次のような文字列がある場合があります。
"(DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(Host = something.cloud.company)
(PORT = 12345)) (ADDRESS = (PROTOCOL = TCP)(Host = something.cloud.company)
(PORT = 12345)) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME =
something.company)))"
SIDの代わりに使用できます。
connection = cx_Oracle.connect("username", "pw", "(DESCRIPTION = (ADDRESS =
(PROTOCOL = TCP)(Host = something.cloud.company)(PORT = 12345)) (ADDRESS =
(PROTOCOL = TCP)(Host = something.cloud.company)(PORT = 12345))
(CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = something.company)))")
それでも動作しない場合があります。 dsnStrの出力を取得し、SIDをSERVICE_NAMEに置き換えて文字列を変更し、con文字列でその変数を使用する必要があります。この手順はうまくいきました。