Tips12. PythonからOracleへの接続

PythonからOracleデータベースに接続

セットアップ概要

PythonからOracleに接続するには、"cx_Oracle"を使用します。
cx_Oracle はpipでインストールすることが出来ますが、cx_Oracleを使用するためには、事前に Oracle Instant Clientのインストールが必要です。

尚、この記事は、Ubuntu18.04, Python3.6.9, Oracle12.1cで確認を行っています。

Oracle Instant Clientのインストール(for Linux(Ubuntu))

基本的にはOracle Linuxでの使用を想定されているようですが、Ubuntuからでも使用可能です。

下記のサイトからZIPファイルをダウンロードします。
(Oracle Linuxを含む、Redhat系のrpmを使用されている方は、rpmの方が便利でしょう)

Oracle Instant Client Downloads
https://www.oracle.com/database/technologies/instant-client/downloads.html
Basic Package (ZIP)

インストール手順は、ダウンロードサイトの後方に記載があります。
https://www.oracle.com/database/technologies/instant-client/linux-x86-64-downloads.html#ic_x64_inst

今回は少し古い18.5のインストール例ですが、19~21あたりでは特に違いはないはずです。

ダウンロードファイルの解凍

ファイルをダウンロードしたら下記のように解凍します。
ダウンロードしたZIPファイルは、$HOME/oracle に配置されていることを想定。
インストール先は /opt/oracle の場合です。

cd /opt
mkdir oracle
cp -a $HOME/oracle/instantclient-basic-linux.x64-18.5.0.0.0dbru.zip /opt/oracle/
unzip instantclient-basic-linux.x64-18.5.0.0.0dbru.zip

18.3以前ではlibclntsh、libocciのリンクを手動で作成する必要があります。18.3以降では自動で作成されるようです。

追加モジュールのインストール

ubuntuでは、追加モジュールとして「libaio1」のインストールが必要です。
下記のようにインストールします。

sudo apt install libaio1

Oracle Linuxでは「libaio」という名前になります。コマンドは下記のようになります。

sudo yum install libaio

パスの設定

LD_LIBRARY_PATH, PATH 環境変数を設定します。
インストール先のディレクトリを環境変数に加えてください。

export LD_LIBRARY_PATH=/opt/oracle/instantclient_18_5:$LD_LIBRARY_PATH
export PATH=/opt/oracle/instantclient_18_5:$PATH

cx_Oracleのインストール

pipコマンドでインストールします。
(pipかpip3かは環境に合わせてください)

pip3 install cx_Oracle

次章のサンプルプログラムでは、接続情報を環境変数に保持するため、次のモジュールもインストールします。

pip3 install python-dotenv

cx_Oracle を使用してOracleに接続確認

先に、接続情報を記載した、db.envファイルを作成します。

DBUSR = 'scott'
DBPWD = 'tiger'
DBCON = 'oradb1:1521/pdbora1'

接続文字列(DBCON)は、[ホスト名]:[ポート番号]/[サービス名] で記載します。

次のサンプルプログラムを実行します。
データベースはお馴染みの、scott/tiger でempテーブルからデータを取得します。
前に作成したdb.envファイルと同じディレクトリに置いてください。

import os
from dotenv import load_dotenv
import cx_Oracle
load_dotenv('./db.env')
DBUSR = os.environ.get("DBUSR")
DBPWD = os.environ.get("DBPWD")
DBCON = os.environ.get("DBCON")
stocklistsql="SELECT empno, ename FROM emp WHERE empno >= :pempno ORDER BY empno"
try:
    # DB接続の取得
    conn = cx_Oracle.connect(DBUSR, DBPWD, DBCON)
    # カーソルオープン
    cur = conn.cursor()
    # カーソルへSQLの定義
    cur.prepare(stocklistsql)
    # SQLの実行
    cur.execute(None, {'pempno':7900})
    # 取得結果を配列変数rstに格納
    rst = cur.fetchall()
    # カーソルクローズ
    cur.close()
    # DB接続クローズ
    conn.close()
    print(str(rst))
except (cx_Oracle.DatabaseError) as expt:
    print("[ERROR] Failed to connect to Database.")
    print("[ERROR cx_Oracle] %s" % str(expt))
    exit(1)

下記の結果が出力されたら成功です。

[(7900, 'JAMES'), (7902, 'FORD'), (7934, 'MILLER')]

次の結果が出たら、ユーザー名かパスワードが間違っています。

[ERROR] Failed to connect to Database.
[ERROR cx_Oracle] ORA-01017: invalid username/password; logon denied

2021-11-08Oracle, PythonOracle, Python

Posted by tfurukaw