1. はじめに
Compute に jupyter notebook をインストールし、python で ADB に接続してみます。
以下のライブラリを使用します。
インストールするライブラリ |
---|
python-oracledb |
sqlalchemy |
pandas |
前提条件
https://qiita.com/twakimura/items/576d569bf195ef81280e
この記事を参考に Compute インスタンスから ADB への接続設定を行っています。
2. python のバージョン更新
oracleDB に接続するためのライブラリ python-oracledb は Linux8 にデフォルトでインストールされている python3.6 では非推奨となっています。
$ python --version
Python 3.6.8
そのため、利用する python のバージョンを3.8に更新します。
以下で python3.8 をインストールします。
$ sudo dnf install -y gcc gcc-c++ make
$ sudo dnf install -y python38
ですが、 python3.8 をインストールしただけではデフォルトの python バージョンが変わりません。
$ python --version
Python 3.6.8
$ python3.8 --version
Python 3.8.17
alternatives でデフォルトの python を変更します。
ここでは4番に python3.8 がリストされていたため、4をデフォルトに指定しています。
$ sudo alternatives --config python
There are 4 programs which provide 'python'.
Selection Command
-----------------------------------------------
* 1 /usr/libexec/no-python
2 /usr/bin/python2
+ 3 /usr/bin/python3
4 /usr/bin/python3.8
Enter to keep the current selection[+], or type selection number: 4
$ python --version
Python 3.8.17
デフォルトの python バージョンを3.8に変更することが出来ました。
3.jupyter notebookのインストール
ここでは oracle ユーザーのhomeディレクトリに python というディレクトリを作成し、そこを python のhomeディレクトリとしています。
$ sudo dnf update
$ sudo dnf install python3-pip -y
$ sudo python -m pip install --upgrade pip
$ sudo su - oracle
$ mkdir python
$ cd python
$ python -m pip install jupyterlab
上記を実行すると、以下のエラーが発生しました。
SyntaxError: future feature annotations is not defined
----------------------------------------
Command "python setup.py egg_info" failed with error code 1 in /tmp/pip-build-wcm5l4hb/argon2-cffi-bindings/
同様のエラーが発生する場合は、以下の手順で解消できるようです。
# pip3 install --upgrade pip setuptools
# pip3 install ez-setup
上記を実行した後、再度 jupyter-lab をインストールしてみます。
# sudo su - oracle
$ cd python
$ python -m pip install jupyterlab
$ jupyter-lab --ip='0.0.0.0' --NotebookApp.token=''
jupyter が起動したら、起動ログに以下のようなURLが表示されます。
Jupyter Server 2.14.2 is running at:
http://<Instance名>:8888/lab
or http://127.0.0.1:8888/lab
teraterm のSSH転送設定で以下を設定します。
ローカルのポート:8888
リモート側ホスト:localhost
ポート:8888
この状態でブラウザで以下のURLにアクセスすると、teraterm の転送設定で Compute インスタンス上で起動した jupyter notebook にアクセスできます。
http://localhost:8888/lab
jupyter notebook を起動したディレクトリがhomeディレクトリになるため、以下のように alias を切って同じディレクトリがhomeになるようにしておくと便利です。
alias notebook="cd ~/python && jupyter-lab --ip='0.0.0.0' --NotebookApp.token=''"
3.pythonからのADB接続
テーブルにデータを用意します。
SQL> CREATE TABLE TEST
(TESTNO NUMBER(2) PRIMARY KEY,
TESTNAME VARCHAR2(14));
SQL> INSERT INTO TEST VALUES (1, 'テスト1');
SQL> INSERT INTO TEST VALUES (2, 'テスト2');
SQL> commit;
python から oracledb に接続するためのパッケージ python-oracledb と sqlalchemy をインストールします。
取得データの表示に pandas も利用するためあわせてインストールしておきます。
$ pip3 install oracledb
$ pip3 install sqlalchemy
$ pip3 install pandas
ADBへの接続に必要な情報をoracleユーザーの環境変数に設定します。
TNS_ADMIN同様、.bashrcなどに記載しておくと便利です。
$ export ORAUSER=admin
$ export ORAPASS=<adminユーザーのパスワード>
$ export ORATNS=<tnsnames.oraで確認した接続文字列>
$ export WALLETPASS=<walletのパスワード>
環境変数を設定したユーザーで再度 jupyter notebook を起動し、以下の python コードを実行します。
import os
import pandas as pd
from sqlalchemy import create_engine
# 環境変数から情報を取得
un = os.environ.get('ORAUSER')
pw = os.environ.get('ORAPASS')
cs = os.environ.get('ORATNS')
wallet_dir = os.environ.get('TNS_ADMIN')
wallet_pw = os.environ.get('WALLETPASS')
# SQLAlchemyエンジンを作成
engine = create_engine(f'oracle+oracledb://{un}:{pw}@{cs}', connect_args={
"config_dir": wallet_dir,
"wallet_location": wallet_dir,
"wallet_password": wallet_pw
})
# クエリ実行とデータ取得
query = "SELECT * FROM TEST"
with engine.connect() as conn:
df = pd.read_sql(query, con=conn)
df
テーブル内容をpandasのDataframeで取得することができました。
4. データの挿入
ここではcsvファイルからデータinsertしてみます。
以下のcsvを用意します。
"TESTNO","TESTNAME"
3,"テスト3"
pythonのコードは以下です。
import os
import pandas as pd
from sqlalchemy import create_engine
un = os.environ.get('ORAUSER')
pw = os.environ.get('ORAPASS')
cs = os.environ.get('ORATNS')
wallet_dir = os.environ.get('TNS_ADMIN')
wallet_pw = os.environ.get('WALLETPASS')
# SQLAlchemyエンジンを作成
engine = create_engine(f'oracle+oracledb://{un}:{pw}@{cs}', connect_args={
"config_dir": wallet_dir,
"wallet_location": wallet_dir,
"wallet_password": wallet_pw
})
# データの準備
csv = 'data/test.csv'
df = pd.read_csv(csv)
# 既存のテーブルにデータを挿入(テーブル名は小文字で指定)
with engine.connect() as conn:
# 既存のテーブルにデータを追加
df.to_sql('test', con=engine, if_exists='append', index=False)
# 接続を閉じる
engine.dispose()
上記はinsertまでのコマンドサンプルですので、再度照会コマンドを実行するとデータが挿入されていることが確認できます。