【はじめの一歩】OCIのMySQL Database Serviceをつかってみよう！（MDS＋Python 他⑤）:データ取得

# はじめに
講釈よりも、とにかく触りたい・使いたい初心者向け手順書テイスト
OCIのMDSをたてて、Python等で繋げて使ってみる。
今回はConnector/Pythonを利用しDBからのデータ取得です。
前提：OCIの有償アカウントであること（30日間無料トライアルの方もOKです）

本手順は、翔泳社の良書
[MySQL徹底入門 第4版 MySQL 8.0対応](https://www.shoeisha.co.jp/book/detail/9784798161488)を参考としています。
同書籍の[サンプルファイル](https://www.shoeisha.co.jp/book/download/9784798161488)を活用します。
※サンプルファイルのReadMeに以下のありがたいお言葉があるので活用して効率化します。
「本書のサンプルデータは自由に利用できることとします。改変のほか、自由に利用、複製、再配布することができます。」
ただ、サンプルファイルの日本語部分は文字化けしているファイルがあるので、
そのまま使うのが難しい場合があります。

本記事の・・・
OCI環境については[MDS＋Python 他①](https://qiita.com/hm-peasant/items/246b19095e347e568f44)
DB構成については[MDS＋Python 他②](https://qiita.com/hm-peasant/items/07660df8261e6ea16a43)
シンプルな更新については[MDS＋Python 他③](https://qiita.com/hm-peasant/items/c861eb82da6a8ac5aa8a)
プレースホルダーについては[MDS＋Python 他④](https://qiita.com/hm-peasant/items/60ecf35271571f99115e)
をご確認ください。

# 前準備
・MDSの起動
・コンピュートの起動
・Cloud Shellの起動とコンピュートへのSSH接続

```ruby:Cloud Shellからのssh接続
$ ssh -i 秘密キー パブリックIPアドレス -l opc
例：$ ssh -i ssh-key-2022-05-31.key 150.230.193.122-l opc
```
# PYファイルの作成

```ruby:pyファイル作成
$ vi ファイル名.py
ファイルが開かれたら「i」キーを押下した後、処理内容を記入し、
「ESCキー →　:(コロン)　→ wq!」で上書き保存
```

# 前処理
前段で接続処理を記入します。
mysql.connector.connectのカッコ内：user、password、host、databaseを自身の環境に合わせて編集

```ruby:前処理
import mysql.connector
from mysql.connector import errorcode
try:
    conn = mysql.connector.connect(user='mdsuser', password='Mdsp@ss01',
                                   host='10.0.1.51',
                                   database='mdstest', use_pure=True)
    conn.autocommit = True
```

# SELECTクエリー
若干の違いはありますが今までの更新系の処理の部分が、SELECTになっただけなので簡単です。
全件取得のやり方も様々なので、その違いを興味があれば調べてみてください。
早速やっていきましょう。

```ruby:共通処理
cur = conn.cursor(buffered=True)
sql_str = "SELECT * FROM commodity";
```

```ruby:全権取得（fetchall）
print("---　全件取得　---")
cur.execute(sql_str)
rows = cur.fetchall()
for row in rows:
    print(row)

```
```ruby:1件ずつ取得 （fetchone）
print("---　1件ずつ取得 ---")
cur.execute(sql_str)
count = cur.rowcount
for i in range(count):
    row2 = cur.fetchone()
    print(row2)
```
```ruby:イテレーター
print("--- SELECTクエリー実行：カーソルをイテレーターとして使用 ---")
    cur.execute(sql_str)
    for row in cur:
        print(row)
```

```ruby:サイズ指定（fetchmany）
print("--- 指定size分の行データ取得：例３行 ---")
cur.execute(sql_str)
rows2 = cur.fetchmany(3)
print(rows2)
```

```ruby:ディクショナリー型（dictionary）
print("--- カラム番号指定データ取り出し：行データをディクショナリー型で取得 ---")
cur2 = conn.cursor(buffered=True, dictionary=True)
sql_str2 = "SELECT * FROM commodity";
cur2.execute(sql_str2)
for dict in cur2:
    print(dict["name"],dict["price"])
```

```ruby:後処理
except mysql.connector.Error as err:
    print("VendorError:", err.errno)
    print("SQLState:", err.sqlstate)
    print("SQLException:", err.msg)
else:
    cur.close()
    conn.close()
```
# 実行結果

```ruby:全件取得 （fetchall）実行結果
---　全件取得　---
(1, 'Py_トマト001', 100, None, datetime.datetime(2022, 6, 1, 0, 26, 6))
(2, 'Py_リンゴ(10kg)', 4000, None, datetime.datetime(2022, 6, 1, 2, 0, 14))
(3, 'Py_ブドウ(3kg)', 5000, None, datetime.datetime(2022, 6, 1, 2, 0, 14))
(4, 'Py_ミカン(10kg)', 3000, None, datetime.datetime(2022, 6, 1, 2, 0, 14))
(5, 'Py_イワシ', 100, None, datetime.datetime(2022, 6, 1, 2, 0, 14))
(6, 'Py_アジ', 200, None, datetime.datetime(2022, 6, 1, 2, 0, 14))
(7, 'Py_サバ', 300, None, datetime.datetime(2022, 6, 1, 2, 0, 14))
(8, 'Py_サンマ', 400, None, datetime.datetime(2022, 6, 1, 2, 0, 14))
(9, 'Py_マグロ', 900, None, datetime.datetime(2022, 6, 1, 2, 0, 14))
```
```ruby:1件ずつ取得 （fetchone）実行結果
---　1件ずつ取得 ---
(1, 'Py_トマト001', 100, None, datetime.datetime(2022, 6, 1, 0, 26, 6))
(2, 'Py_リンゴ(10kg)', 4000, None, datetime.datetime(2022, 6, 1, 2, 0, 14))
(3, 'Py_ブドウ(3kg)', 5000, None, datetime.datetime(2022, 6, 1, 2, 0, 14))
(4, 'Py_ミカン(10kg)', 3000, None, datetime.datetime(2022, 6, 1, 2, 0, 14))
(5, 'Py_イワシ', 100, None, datetime.datetime(2022, 6, 1, 2, 0, 14))
(6, 'Py_アジ', 200, None, datetime.datetime(2022, 6, 1, 2, 0, 14))
(7, 'Py_サバ', 300, None, datetime.datetime(2022, 6, 1, 2, 0, 14))
(8, 'Py_サンマ', 400, None, datetime.datetime(2022, 6, 1, 2, 0, 14))
(9, 'Py_マグロ', 900, None, datetime.datetime(2022, 6, 1, 2, 0, 14))
```

```ruby:イテレーター実行結果
--- SELECTクエリー実行：カーソルをイテレーターとして使用 ---
(1, 'Py_トマト001', 100, None, datetime.datetime(2022, 6, 1, 0, 26, 6))
(2, 'Py_リンゴ(10kg)', 4000, None, datetime.datetime(2022, 6, 1, 2, 0, 14))
(3, 'Py_ブドウ(3kg)', 5000, None, datetime.datetime(2022, 6, 1, 2, 0, 14))
(4, 'Py_ミカン(10kg)', 3000, None, datetime.datetime(2022, 6, 1, 2, 0, 14))
(5, 'Py_イワシ', 100, None, datetime.datetime(2022, 6, 1, 2, 0, 14))
(6, 'Py_アジ', 200, None, datetime.datetime(2022, 6, 1, 2, 0, 14))
(7, 'Py_サバ', 300, None, datetime.datetime(2022, 6, 1, 2, 0, 14))
(8, 'Py_サンマ', 400, None, datetime.datetime(2022, 6, 1, 2, 0, 14))
(9, 'Py_マグロ', 900, None, datetime.datetime(2022, 6, 1, 2, 0, 14))
```
```ruby:サイズ指定（fetchmany）実行結果
--- 指定size分の行データ取得：例３行 ---
[(1, 'Py_トマト001', 100, None, datetime.datetime(2022, 6, 1, 0, 26, 6)), (2, 'Py_リンゴ(10kg)', 4000, None, datetime.datetime(2022, 6, 1, 2, 0, 14)), (3, 'Py_ブドウ(3kg)', 5000, None, datetime.datetime(2022, 6, 1, 2, 0, 14))]
```
```ruby:ディクショナリー型（dictionary）実行結果
--- カラム番号指定データ取り出し：行データをディクショナリー型で取得 ---
Py_トマト001 100
Py_リンゴ(10kg) 4000
Py_ブドウ(3kg) 5000
Py_ミカン(10kg) 3000
Py_イワシ 100
Py_アジ 200
Py_サバ 300
Py_サンマ 400
Py_マグロ 900
```
今回は以上です。長文お付き合い頂き、ありがとうございました。

【重要】ＭＤＳは安価ですが、使わないのであれば、停止する、もしくは削除するのを忘れずに
　　　　停止だけだと、ストレージは月単位で課金されます。
お片付け方法は、[初回：MDS＋Python 他① お片付け](https://qiita.com/hm-peasant/items/246b19095e347e568f44#%E3%81%8A%E7%89%87%E4%BB%98%E3%81%91)を参考にしてください。