Skip to main content

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()