【Python】python-oracledbでOracleに接続して操作する方法(サンプルコード付き)

python-oracledb を用いて Oracle データベースへ接続して操作をする方法を解説します。
目次
Python で Oracle データベースへ接続する
python-oracledb とは?
python-oracledb は、以前広く使われていて cx_Oracle の後継として Oracle 社が提供する公式の Python ライブラリです。ライブラリ名はシンプルに「oracledb」です。これにより、Oracle データベースに対して Python から簡単に接続・操作することができます。
大きな特徴は、Oracle Client が不要な Thin モードに対応しており、手軽に導入ができる点です。一方で、従来の cx_Oracle 同様の機能を活用したい場合は、Thick モードを使用します。
oracledb のインストール方法
oracledb ライブラリは、PyPI で公開されており、以下のように pip install コマンドで簡単にインストールできます。
pip install oracledb
Thin モードと Thick モードの違いと選び方
oracledb は、Thin モードと Thick モードの2つの動作モードを提供しています。
| モード | 特徴 | Oracle Client |
|---|---|---|
| Thin | 軽量・インストール簡単で基本機能をカバー | 不要 |
| Thick | 高機能であり、従来のcx_Oracle互換 | 必要 |
Thin モードは Oracle Client も不要でとても便利です。Thin モードで問題ない場合は、そのままで十分ですが Advanced Queuing などの Oracle 特有機能を使いたい場合には、Thick モードの使用を検討する必要があります。
oracledb を用いたサンプルプログラム
以降では、oracledb を用いて Oracle データベースへアクセスするためのサンプルプログラムを紹介します。
前提条件
- Python 3.7 以降、無償版の OracleXE がローカルPCにインストールされているものとします。(製品版の Oracle でも問題ありません。)
- サービスは、Oracle XE デフォルトとして作成される
XEPDB1を使用しています。お使いの環境のサービスにあわせて変更してください。 - ユーザーとして
TESTが作成されておりパスワードはPAssw0rdとしています。お使いの環境にあわせて変更してください。 - 使用するユーザーには、データベースへのアクセス、テーブル作成、データ登録、検索といった権限が付与されているものとします。
- DB接続クラスは
db_connect_oracle.pyに、設定情報はdbconfig.iniとして、dbconfig.iniは、Pythonプログラムと同フォルダに配置とします。
サンプルコード
設定ファイルおよびDBアクセスクラス定義
oracledb を使用して Oracle データベースへアクセスするための設定ファイルとDBアクセス用クラスの例は以下のようになります。設定ファイルの内容はお使いの環境にあわせて修正してください。
【dbconfig.ini】DBアクセス設定ファイル
[ORACLE_DB_SERVER] host = localhost port = 1521 service = XEPDB1 user = TEST password = PAssw0rd
【db_connect_oracle.py】DBアクセスクラス
import configparser
import oracledb
class DbConnectOracle:
"""Oracle DBアクセスクラス"""
def __init__(self, mode: str = "thin", client_lib_dir: str = None) -> None:
"""コンストラクタ
Args:
mode: "thin" または "thick"
client_lib_dir: Thick モードの場合は、Oracle Client のライブラリパス
"""
# モード判定
if mode == "thick":
if client_lib_dir is None:
raise ValueError(
"Thick モードでは client_lib_dir の指定が必要です。"
)
oracledb.init_oracle_client(client_lib_dir)
elif mode != "thin":
raise ValueError(
"mode は、'thin' または 'Thick' を指定してください。"
)
# iniファイルの読み込み
config_db = configparser.ConfigParser()
config_db.read("dbconfig.ini")
# 設定の読み込み
host = config_db["ORACLE_DB_SERVER"]["host"]
port = int(config_db["ORACLE_DB_SERVER"]["port"])
service_name = config_db["ORACLE_DB_SERVER"]["service"]
user = config_db["ORACLE_DB_SERVER"]["user"]
password = config_db["ORACLE_DB_SERVER"]["password"]
# DSN の作成
self.dsn = oracledb.makedsn(host, port, service_name=service_name)
# 接続の確立
self.con = oracledb.connect(
user=user,
password=password,
dsn=self.dsn,
)
self.cursor = self.con.cursor()
def execute_non_query(self, sql: str, bind_var: dict = None) -> None:
"""SQL 実行メソッド
(CREATE / INSERT / UPDATE / DELETE 用)
Args:
sql: 実行SQL
bind_var: バインド変数
Returns: None
"""
# SQLの実行
if bind_var is None:
self.cursor.execute(sql)
else:
# バインド変数がある場合は指定して実行
self.cursor.execute(sql, bind_var)
def execute_query(
self, sql: str, bind_var: dict = None, count: int = 0
) -> list:
"""SQL 実行メソッド
(SELECT 用)
Args:
sql: 実行SQL
bind_var: バインド変数
count: データ取得件数
Returns: 取得結果リスト
"""
# SQLの実行
if bind_var is None:
self.cursor.execute(sql)
else:
# バインド変数がある場合は指定して実行
self.cursor.execute(sql, bind_var)
columns = [col[0] for col in self.cursor.description]
self.cursor.rowfactory = lambda *args: dict(zip(columns, args))
# 取得結果を返却 (件数指定がある場合は、指定された件数分返却)
return (
self.cursor.fetchall()
if count == 0
else self.cursor.fetchmany(count)
)
def commit(self) -> None:
"""コミット
Returns: None
"""
self.con.commit()
def rollback(self) -> None:
"""ロールバック
Returns: None
"""
self.con.rollback()
def __del__(self) -> None:
"""デストラクタ
Returns: None
"""
self.cursor.close()
self.con.close()
if __name__ == "__main__":
pass使用例(Thin モード)
oracledb の Thin モードを使用して上記で作成したクラスを用いてOracleへの接続をするには以下のように使用します。
from db_connect_oracle import DbConnectOracle
def main():
# Thin モードでアクセスする場合
db_oracle = DbConnectOracle()
# ===== テーブルを作成する
create_sql = (
"CREATE TABLE SAMPLE_TABLE"
"("
"ID NUMBER GENERATED ALWAYS AS IDENTITY,"
"STR1 VARCHAR2(50), "
"VALUE1 NUMBER, "
"LAST_UPDATE_DATETIME TIMESTAMP, "
"PRIMARY KEY (ID)"
")"
)
db_oracle.execute_non_query(create_sql)
# コミット
db_oracle.commit()
# ===== データをINSERTする
insert_sql = (
"INSERT INTO SAMPLE_TABLE "
"(STR1, VALUE1, LAST_UPDATE_DATETIME) "
"VALUES(:str1, :val1, CURRENT_TIMESTAMP)"
)
for i in range(5):
input_str = f"test_str{i}"
input_val = 10 * i
bind = {"str1": input_str, "val1": input_val}
db_oracle.execute_non_query(insert_sql, bind)
# コミット
db_oracle.commit()
# ===== データを検索する (全て検索)
print("===== 全件検索")
select_sql = "SELECT * FROM SAMPLE_TABLE"
select_result = db_oracle.execute_query(select_sql)
print(select_result)
# ===== 件数を指定して検索する (以下の例は3件)
print("===== 取得する件数の指定")
select_sql = "SELECT * FROM SAMPLE_TABLE"
select_result = db_oracle.execute_query(select_sql, count=3)
print(select_result)
# ===== 条件を指定して検索する
print("===== 条件を指定して実行する")
select_sql = "SELECT * FROM SAMPLE_TABLE WHERE VALUE1 > :val1"
print("条件1")
select_result = db_oracle.execute_query(select_sql, {"val1": 10})
print(select_result)
print("条件2")
select_result = db_oracle.execute_query(select_sql, {"val1": 30})
print(select_result)
if __name__ == "__main__":
main()
使用例(Thick モード)
oracledb の Thick モードを使用する場合には、クラスをインスタンス化する際に以下の引数を設定してください。
mode:"thick"client_lib_dir:Oracleクライアントライブラリが格納されているパス
以下の例では、Oracle の Instant Client (軽量版クライアント) を使用した場合の例です。フルのOracle Clientの場合は、環境にあわせて r"C:\oracle\product\19.0.0\client_1\bin" のような指定をしていただければいいかと思います。
from db_connect_oracle import DbConnectOracle
def main():
mode = "thick"
client_lib_dir = r"C:\oracle\instantclient_21_18"
# Thick モードでアクセスする場合
db_oracle = DbConnectOracle(
mode=mode,
client_lib_dir=client_lib_dir,
)
# 以降は、Thin モードと同じ
# ・・・
if __name__ == "__main__":
main()サンプルコードのポイント解説
DBアクセス用クラス DBConnectOracle
DBアクセス用のクラスとして DbConnectOracle というクラスを定義しています。メソッドとして定義しているものは以下になります。
| メソッド名 | 概要 |
|---|---|
__init__ | コンストラクタでデフォルトは Thin モードでDBのコネクション確立とカーソル作成を行います。Thick モードで使う場合は、mode の指定と Oracle Client のライブラリパスの指定が必要です。 |
execute_non_query | CREATE / INSERT / UPDATE / DELETEの処理用のSQL実行メソッドです。SQL文と必要に応じてバインド変数を渡して処理を実行します。 |
execute_query | SELECT 用の SQL 実行メソッドです。返却値は辞書 (dict) のリストになります。SQL 文と必要に応じてバインド変数、データ取得件数を渡して処理を実行します。 |
commit | コミットして変更内容を確定します。 |
rollback | ロールバックして変更内容を破棄します。 |
__del__ | デストラクタです。接続終了時にデータベースのカーソルとコネクションをクローズします。 |
まとめ
python-oracledb を用いてOracleデータベースへアクセスする方法について解説しました。
このライブラリは、Oracle 公式であり、Oracle アクセス手段として非常に強力です。これまで使われていた cx_Oracle の後継として使用することができます。
Thin モードと Thick モードが用意されており、Thin モードではOracle Client不要で手軽に使用することができます。また、高度な機能が必要であれば Thick モードの使用を検討してください。
この記事では、汎用的に使えるDBアクセスクラスを作成して OracleDB へのアクセスをできるようにしてみました。ぜひ、参考にしていただいて Oracle 接続に活用していただければと思います。
上記で紹介しているソースコードについては GitHub にて公開しています。参考にしていただければと思います。

