Python から Oracle 接続方法
前提
- Oracle Client ライブラリをインストールしてること
- Thin モードの場合 : brew 版でも良い (or インストール不要?)
- Thick モードの場合 : Oracle Instant Client (純正版) が必要
- 詳細
Pythonライブラリのインストール
pip install oracledb
select サンプル1: 最小構成 (Thin Client でも使える)
py
#!/usr/bin/env python3
import oracledb
db_user = "sugoi_user"
db_pass = "sugoi_pw"
dsn = "localhost:1521/orclpdb"
connection = oracledb.connect(user=db_user, password=db_pass, dsn=dsn)
cursor = connection.cursor()
cursor.execute("SELECT TO_CHAR(sysdate, 'YYYYMMDD') as dt FROM dual")
for row in cursor:
print(row) # => ('20250429',) : tuple
cursor.close()
connection.close()
select サンプル2: 基本はこのように使いたい (Thick Client + Dictionary)
以下のように変更した版
- Thick モードにする
- tnsnames.ora の登録名を使用
- with を使用して close 漏れを防ぐ
- 結果を tuple でなく dictionary にする
py
#!/usr/bin/env python3
import oracledb
db_user = "sugoi_user"
db_pass = "sugoi_pw"
dsn = "ORCLPDB" # tnsnames.ora の登録名にする
# Thickモード(Oracleクライアントを使うモード)を有効にする
oracledb.init_oracle_client(lib_dir="/opt/oracle/instantclient_23_3")
# with を使用して close 漏れを防ぐ場合
with oracledb.connect(user=db_user, password=db_pass, dsn=dsn) as connection:
with connection.cursor() as cursor:
cursor.execute("SELECT TO_CHAR(sysdate, 'YYYYMMDD') as dt FROM dual")
# 結果を tuple でなく dictionary にする
columns = [col.name for col in cursor.description]
cursor.rowfactory = lambda *args: dict(zip(columns, args))
# ここで fetch される (設定した rowfactory が使われる)
for row in cursor:
print(row) # => {'DT': '20250429'}
# または、配列としてほしい場合は fetchall() で取得
# rows = cursor.fetchall()
データ更新サンプル1
py
with connection.cursor() as cursor:
cursor.execute("""
INSERT INTO your_table_name (id, name)
VALUES (your_seq.NEXTVAL, :name)
""", {"name": "Taro"})
connection.commit()
- このプレースホルダ置換の書き方で SQL インジェクション対策される
- insert, update, delete は同様なので省略
- truncate, create, drop も同様だが、commit 要らない。(プレースホルダもない)
データ更新サンプル2 (bulk insert)
py
data = [
{"name": "Taro"},
{"name": "Hanako"},
{"name": "Jiro"}
]
with connection.cursor() as cursor:
cursor.executemany("""
INSERT INTO your_table_name (id, name)
VALUES (your_seq.NEXTVAL, :name)
""", data)
connection.commit()
データ更新サンプル3 (トランザクション管理)
py
try:
with connection.cursor() as cursor:
cursor.execute("""
INSERT INTO your_table_name (id, name)
VALUES (your_seq.NEXTVAL, :name)
""", {"name": "Saburo"})
connection.commit()
except Exception as e:
print(f"エラー発生: {e}")
connection.rollback()