PythonでOracle接続してデータ検索する方法のメモ。
環境
OS | Python | Oracle Client |
---|---|---|
CentOS 6.4 | 3.3.0 | 11.2.0.3.0 |
インストール
Oracleへの接続ライブラとして、cx_Oracleをインストールする。
Oracleクライアントは既にインストールされている環境を使用したので、そちらのインストールは省略。(多分以下の4つのrpmをインストールした環境のはず)
- oracle-instantclient11.2-basic-11.2.0.3.0-1.x86_64.rpm
- oracle-instantclient11.2-precomp-11.2.0.3.0-1.x86_64.rpm
- oracle-instantclient11.2-devel-11.2.0.3.0-1.x86_64.rpm
- oracle-instantclient11.2-sqlplus-11.2.0.3.0-1.x86_64.rpm
まずは、cx_Oracleインストールに必要なpython3-develのインストール。
$ sudo yum install python3-devel 読み込んだプラグイン:fastestmirror, refresh-packagekit, security インストール処理の設定をしています Loading mirror speeds from cached hostfile * PUIAS_6_computational: puias.math.ias.edu * base: ftp.iij.ad.jp * centosplus: centos.mirror.secureax.com * epel: epel.mirror.srv.co.ge * extras: centos.mirror.secureax.com * updates: ftp.iij.ad.jp 依存性の解決をしています --> トランザクションの確認を実行しています。 ---> Package python3-devel.x86_64 0:3.3.0-1.puias6 will be インストール --> 依存性解決を終了しました。 依存性を解決しました =================================================================================================================== パッケージ アーキテクチャ バージョン リポジトリー 容量 =================================================================================================================== インストールしています: python3-devel x86_64 3.3.0-1.puias6 PUIAS_6_computational 169 k トランザクションの要約 =================================================================================================================== インストール 1 パッケージ 総ダウンロード容量: 169 k インストール済み容量: 532 k これでいいですか? [y/N]y パッケージをダウンロードしています: python3-devel-3.3.0-1.puias6.x86_64.rpm | 169 kB 00:01 rpm_check_debug を実行しています トランザクションのテストを実行しています トランザクションのテストを成功しました トランザクションを実行しています インストールしています : python3-devel-3.3.0-1.puias6.x86_64 1/1 Verifying : python3-devel-3.3.0-1.puias6.x86_64 1/1 インストール: python3-devel.x86_64 0:3.3.0-1.puias6 完了しました!
続いて、cx_Oracleのインストール。
$ echo $ORACLE_HOME /usr/lib/oracle/11.2/client64 $ sudo ln -s /usr/include/oracle/11.2/client64 $ORACLE_HOME/include $ su # echo /usr/lib/oracle/11.2/client64/lib >> /etc/ld.so.conf.d/oracle.conf $ sudo ldconfig $ pip install cx_Oracle (途中略) Successfully installed cx-Oracle Cleaning up...
環境設定(クライアント環境)
自分の環境のOracle周りの設定。 LD_LIBRARY_PATHの設定は必須。 他は関係ない設定もあると思うけどメモがてら載せとく。
export ORACLE_HOME=/usr/lib/oracle/11.2/client64 TNS_ADMIN=$ORACLE_HOME/network/admin export TNS_ADMIN export NLS_LANG=Japanese_Japan.AL32UTF8 NLS_DATE_FORMAT='YYYYMMDDHH24MISS' export NLS_DATE_FORMAT NLS_TIMESTAMP_FORMAT='YYYYMMDDHH24MISS.FF3' export NLS_TIMESTAMP_FORMAT export PATH=$PATH:$HOME/bin:$ORACLE_HOME/bin export LD_LIBRARY_PATH=.:$ORACLE_HOME/lib:/lib:/usr/lib:/usr/local/lib
データ取得
テーブルからデータを取得して表示してみた。
$ python3 Python 3.3.0 (default, Feb 12 2013, 17:01:04) [GCC 4.4.6 20120305 (Red Hat 4.4.6-4)] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import cx_Oracle >>> conn=cx_Oracle.connect('scott','tiger','xx.xx.xx.xx/tns_service_name') >>> cur=conn.cursor() >>> sql="select * from scott.db_tbl where rownum<20" >>> cur.execute(sql) <cx_Oracle.Cursor on <cx_Oracle.Connection to scott@xx.xx.xx.xx/tns_service_name>> >>> rows=cur.fetchmany(10) >>> print(len(rows)) 10 >>> print(cur.rowcount) 10 >>> for row in rows: ... print(row) ... (tupleデータ10行出力) >>> rows=cur.fetchmany(10) >>> print(len(rows)) 9 >>> print(cur.rowcount) 19 >>> for row in rows: ... print(row) ... (tupleデータ9行出力) >>> rows=cur.fetchmany(10) >>> print(len(rows)) 0 >>> print(cur.rowcount) 19 >>> cur.close() >>> conn.close()
この内容を元にして、テーブルレコード全件をCSVファイルに出力するPythonスクリプト作ってみた。
#!/usr/bin/python3 import cx_Oracle import sys import csv from itertools import chain argvs = sys.argv argc = len(argvs) if argc != 2: print('Usage: %s TableName' % argvs[0]) quit() table_name = argvs[1].upper() file_name = table_name + '_data.csv' with cx_Oracle.connect('scott','tiger','xx.xx.xx.xx/tns_service_name') as conn: # テーブルの列名取得 column_name_sql = 'select column_name from user_tab_columns where table_name = :tbl' cur_columns = conn.cursor() cur_columns.execute(column_name_sql, tbl=table_name) columns = cur_columns.fetchall() cur_columns.close() columns = tuple(chain.from_iterable(columns)) # テーブルのレコード全件取得 data_sql = 'select * from %s' % table_name cur_data = conn.cursor() cur_data.execute(data_sql) with open(file_name, 'w') as f: csv_writer = csv.writer(f) csv_writer.writerow(columns) while 1: rows = cur_data.fetchmany(50) if len(rows) == 0: break csv_writer.writerows(rows) cur_data.close()
参考:
pythonからOracleに接続するための拡張モジュール、cx_Oracleの基本的な使い方 at nkjmkzk.net
UbuntuでPythonからcx_Oracleモジュールを使ってOracle Database 11gに接続する - 偏った言語信者の垂れ流し
Cursor Object — cx_Oracle 5.1.3 documentation