検証環境
- Oracle Cloud利用
- Oracle Linux 7.7 (VM.Standard2.1)
- Python 3.6
- cx_Oracle 7.3
- Oracle Database 19.5 (ATP, 1OCPU)
- Oracle Instant Client 18.5
SELECT処理の基本
SELECTに限らず、SQL文を発行するためには、まず、以下のような形でCurosrオブジェクトを作成する必要があります。
cursor = connection.cursor()
続けて、例えば
cursor.execute("select sysdate from dual")
と、引数にSELECT文を指定して、Curosrオブジェクトのexecute()メソッドをコールします。コール結果をfor文でループさせることにより、レコードがタプルの形で取り出されます。最後はCurosrオブジェクトを
cursor.close()
でクローズさせます。以下実行サンプルです。ALL_OBJECTSビューをOBJECT_ID順に5件取り出す形なので、何等かcx_Oracleアプリケーションを動かした実績があるなら、特段の事前準備なしで動くと思います。
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import cx_Oracle
USERID = "admin"
PASSWORD = "FooBar"
DESTINATION = "atp1_low"
SQL = """
select object_id, owner, object_name, object_type
from all_objects
order by object_id
fetch first 5 rows only
"""
with cx_Oracle.connect(USERID, PASSWORD, DESTINATION) as connection:
cursor = connection.cursor()
cursor.execute(SQL)
for row in cursor:
print(row)
cursor.close()
筆者環境では、以下のような出力になります。
$ python sample03a.py
(2, 'SYS', 'C_OBJ#', 'CLUSTER')
(3, 'SYS', 'I_OBJ#', 'INDEX')
(4, 'SYS', 'TAB$', 'TABLE')
(5, 'SYS', 'CLU$', 'TABLE')
(6, 'SYS', 'C_TS#', 'CLUSTER')
Curosrオブジェクトとwith構文
上記サンプルではConnectionオブジェクトに対してのみwith構文を使用していますが、Curosrオブジェクトもwith構文に対応しています。ですので、上記サンプルの最後の6行を以下のよう書き換えると、より簡素な記述量でカーソル数不足(ORA-1000)のようなトラブルが発生しにくい、より安全なコーディングとなります。おまけでSQL発行部分も短縮してみました。
with cx_Oracle.connect(USERID, PASSWORD, DESTINATION) as connection:
with connection.cursor() as cursor:
for row in cursor.execute(SQL):
print(row)
リスト内包表記
結果セットをリストでまとめて扱いたい場合は、以下のように、リスト内包表記の利用も可能です。なお、環境次第ですが、下記サンプルの実行のためには、pprintモジュールの事前インストールが必要です。
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import cx_Oracle
import pprint
USERID = "admin"
PASSWORD = "FooBar"
DESTINATION = "atp1_low"
SQL = """
select object_id, owner, object_name, object_type
from all_objects
order by object_id
fetch first 5 rows only
"""
with cx_Oracle.connect(USERID, PASSWORD, DESTINATION) as connection:
with connection.cursor() as cursor:
pprint.pprint([f"{r[1]}.{r[2]}は{r[3]}(ID:{r[0]})です" for r in cursor.execute(SQL)])
$ python sample03c.py
['SYS.C_OBJ#はCLUSTER(ID:2)です',
'SYS.I_OBJ#はINDEX(ID:3)です',
'SYS.TAB$はTABLE(ID:4)です',
'SYS.CLU$はTABLE(ID:5)です',
'SYS.C_TS#はCLUSTER(ID:6)です']