Pythonプログラム Oracleへの接続

 今日も見に来てくださって、ありがとうございます。今回は、pythonからOracleへ接続して、テーブルをつくったり、データをINSERT、SELECT、UPDATE、DELETEなどをやってみようと思います。

準備(まずはインストール)

 ぼくの現在の環境は、Windows10、Anaconda3(64bit)です。今回Oracleへ接続するためのモジュールに、cx_Oracleを使います。ちなみに、OracleはExpress Edition 18cです。Pythonでモジュールのインストールといえば、pipを使いますが、Anacondaの場合は、condaというコマンドを使うと整合性の取れたちょうど良いものを入れてくれるようなので、そちらを利用します。やり方がわからないときは、すぐにgoogle先生に聞いてみます。はい、インストールのやり方、ここにありましたね。ちなみに、cx_Oracleについては、丁寧なドキュメントがここにありました。(英語です。)

conda install -c anaconda cx_oracle

 コマンドが分かりましたので、手順を説明していきます。

まずは、Anacondaプロンプトの起動です。Windowsのメニューから以下の「Anaconda Prompt」を選択します。

Windows メニュー

すると、以下のようなプロンプト画面が表示されます。

Anaconda Prompt

 ここで、先ほどのコマンドを入力しましょう。おっと、condaの新しいバージョンが出ているといわれていました。

condaコマンドを走らせてアップデートしてください、ということなので、アップデートするのに、いったん中断しましょう。「Proceed ([y]/n)?」(続けますか?)と聞かれますのでnを入力、Enterキーを押して中断します。そして、今度は以下のcondaコマンドを更新するためのコマンドを入力して、結果を見ましょう。途中で「Proceed ([y]/n)?」(続けますか?)と聞かれますので、今度はyを入力してEnterを押して続けてください。

conda update -n base -c defaults conda

無事成功、ですね!
…と、思いましたが、正しくインストールできなかったようです。

失敗していました。

 ぱっと見た目はダウンロードして、解凍に成功していますので、バッチリできたねぇ、と、勘違いしても仕方ありませんよね。よく見ると「EnvironmentNotWritableError」という「環境が書き込みできないエラー」が発生しているようです。「The current user does not have write permissions to the target environment.」現在のユーザはターゲットの環境への書き込み権限を持っていません、ということですね。
 舞い戻って最初のコマンド入力のメッセージもよくよく眺めてみていたら、なんと、衝撃の事実が。あ、たいした事実ではありませんよ。(笑)

衝撃の事実

 そう、condaも一緒にアップデートされますよ、と記載があるじゃないですか。止めなくてもよかったのに。と、いうことで気を取り直して、書き込み権限のある状態でcondaを実行したいと思います。個別の権限設定があるかどうかは分かりませんが、こういう時はいつもAnaconda Promptを管理者権限で起動してからcondaコマンドを実行しています。

Anaconda Promptを管理者として実行

 Anaconda Promptを管理者として実行するために、Windowsメニューから「Anaconda Prompt」を右クリック、「その他」の「管理者として実行」を選択します。これで今度は成功するはず。ユーザーアカウント制御のダイアログボックスが表示された場合には、「このアプリがデバイスに変更を加えることを許可しますか?」の質問に対して「はい」を選択してください。これで今度は管理者としてAnaconda Promptが実行されました。

 左上に「管理者」と出力されていますね。
 では、気を取り直して再び先ほどのコマンドを実行します。

conda install -c anaconda cx_oracle

 今度こそ成功だね、と、思いましたが、なんと、またしてもエラーが発生。

またしてもエラー発生

 アクセスが拒否されました、ということですが、、、管理者権限で実行したのにねぇ。Qtのパッケージにアクセスするのに失敗しているようですね。ええと、もしかしたら、開発環境(IDE)のSpyderを使っているのが原因でしょうか。ぜんぜん気にしていませんでしたが、Spyderが起動中でした。Spyderも確かQtを利用していたと思いますので、おそらくこいつが掴んでいるためにアクセスが拒否されたのでしょうね。と、いうことでSpyderを終了してもう一度実行してみます。

今度はやっと成功しました。

 若干先ほどのパッケージと内容が変わっているのが気になりますが、なんとか成功したようです。

接続確認

 では、さっそく接続確認してみます。接続確認のスクリプトは以下の通りです。

import cx_Oracle

username = "ishikawa" # ユーザー名は適宜変更してください。
password = "********" # パスワードも適宜変更してください。
conn = cx_Oracle.connect(username, password, "127.0.0.1:1521/xepdb1")
print(conn.version)

 最初に必要なのは、import cx_Oracleとcx_Oracleモジュールをインポートすることです。接続には、モジュールで定義されているconnectメソッドを使います。接続後、versionが出力できれば、接続ができた、ということが確認できるでしょう。

接続成功!

はい、接続に成功したようです!

テーブル作成

 では、続けてテーブルを作成します。コネクションからcursor()を呼び出してカーソルを作成して、カーソルからexecute()を使ってSQLを実行します。

cur = conn.cursor()
cur.execute("create table poi( n number, v varchar2(20), c char(10), d date )")
テーブル作成成功!

 はい、成功したようです。念のため、SQL*Plusで確認してみました。あ、ちなみにSQL*Plusとは、Oracleのコマンドラインツールで、SQLを発行したり、結果をファイルへ出力したりできる、基本的なツールです。Oracleをインストールした環境にはたいていインストールされていますので、いろいろな現場へ行く人は使い方に習熟しておくとよいと思います。

テーブル作成結果をSQL*Plusで確認

 ちゃんと作成されてましたね。

データのINSERT、SELECT、UPDATE、DELETE

 次に、SQLのDMLを確認していきたいと思います。スクリプトは以下の通りです。

cur.execute("insert into poi values ( 1, 'abc', 'def', sysdate )")
for row in cur.execute("select * from poi"):
    print(row)

cur.execute("update poi set n = 2 where n = 1")
conn.commit()
cur.execute("delete from poi where n = 2")
conn.commit()

 まずINSERTを実行して、内容をSELECTしてみます。そして、UPDATEしてから内容をコミットします。

INSERT、SELECT、UPDATE、COMMITの実行結果

 ごらんの通り、SELECTの結果はタプルのシーケンスとして戻されるのですね。日付はdatetimeモジュールのdatetimeで戻されるのですね。なるほど。
 ちゃんと更新されているかどうか、SQL*Plusからも確認してみます。

INSERT、UPDATE、COMMITの結果をSQL*Plusから確認

 ちゃんとNが2に更新されていますね。続いてDELETEを実行して、コミットします。

DELETEとCOMMITの実行

再度、SQL*Plusから確認してみます。

DELETEとCOMMITの実行結果をSQL*Plusから確認

 はい、ちゃんと削除されていました。

まとめ

 今回、cx_Oracleを使ってオラクルへ接続して、簡単なSQLを発行してみました。とりあえずはこれだけできるようになっていれば、簡単なアプリケーションは実現できそうですね。でも、エラー発生時のハンドリングとか、ストアドプログラムの呼び出しとか、変数をバインドしたりとか、ちょっと考えただけでもまだまだやらないといけないこと、たくさんありますね。また機会があれば、書いていきたいと思います。

 今回の注意点としては、インストールはcondaコマンドを管理者権限で実行する。このとき余計なプログラムは終了させておく。インストールのメッセージが英語だからと出力を適当に流さない、ということぐらいでしょうかねぇ。

“Pythonプログラム Oracleへの接続” への1件の返信

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です


The reCAPTCHA verification period has expired. Please reload the page.