WindowsでDockerを使ってみた２

## 内容
・趣旨目標
・前回の記事からの続き。
・現状の構成
・作りたい構成
・作りたい構成の細部
・補備修正箇所
・Pythonコードを改良！
・dockerfileを編集していく。
・MySQLをインストール＆コンテナ作成
・Pythonの実行


## 趣旨目標
前回の記事に引き続きアプリを改良し、BDの追加を行う。細部は以下のとおり。

## 前回の記事からの続き。
前回の記事：
https://qiita.com/nikorasu277/items/45277016248c380f9971

## 現状の構成：
windows11,WSL,ubuntu,VSCode,Docker,Python
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3518951/b4a30ec0-a2ef-6b27-5d1e-45bab2cde6c4.png)


## 作りたい構成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3518951/3c97bab8-3151-c40b-8cec-06f83970df17.png)



## 作りたい構成の細部
【１】
Pythonのコードを改良し、dfを作成するところまでは現状のコードであるので、dfをCSVにエクスポートする。
【２】
MySQLをインストールしてテーブルを作成、カラムは現状のExcelに合わせて２個、文字列と数値。CSVをインポートしてレコードを作成。
【３】
以上の変更点をコンテナ内で完結するべし。


## 補備修正箇所：
MySQLは日本語に対応しています。設定方法も理解していますが、Excelを英語表記に編集します。my.cnfファイルがMySQLコンテナ内に存在しないため、今回は素直に英語表記に修正するかたちで進めます。伴ってカラム名も英語表記でいきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3518951/14eaba17-4de6-d1ee-1cdc-2d4d17b2a1db.png)



## Pythonコードを改良！
現状⇒
```
import pandas as pd
df = pd.read_excel("sample.xlsx")
print(df)
```

dfをCSVでエクスポートします。改良⇒
・最初にコンテナ内ターミナルでpipをインストール。PythonとMySQLを接続するもの。
```
pip install pymysql
```

・app.pyを編集していく。
最初にMySQLコンテナのIPアドレスを確認
```
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' <コンテナ名またはID>
```
```
import pandas as pd
import pymysql
import csv

df = pd.read_excel("sample.xlsx")
df.to_csv("data.csv", index=False)

# MySQLに接続
connection = pymysql.connect(host='172.17.0.2',
                             user='root',
                             password='keiji',
                             db='keiji_db',
                             charset='utf8mb4',
                             cursorclass=pymysql.cursors.DictCursor)

try:
    with connection.cursor() as cursor:
        # テーブル作成
        create_table_query = """
        CREATE TABLE IF NOT EXISTS `Fruit prices` (
            `name` VARCHAR(255),
            `price` DECIMAL(10, 2)
        )
        """
        cursor.execute(create_table_query)

        # CSVファイルからデータを読み込んで挿入
        with open('data.csv', 'r') as file:
            next(file)  # ヘッダーをスキップ
            csv_data = csv.reader(file)
            for row in csv_data:
                cursor.execute("INSERT INTO `Fruit prices` (name, price) VALUES (%s, %s)", row)

    # 変更をコミット
    connection.commit()

finally:
    # 接続をクローズ
    connection.close()
```
indexをTrueにすると期待した表示にならないこと多しなので、数字が必要であれば手人力で入れましょう。
ここまでコードを作成したらひとまず保存。


## dockerfileを編集していく。
現状⇒
```
FROM python:3.11.4
RUN pip install pandas
RUN pip install openpyxl
RUN pip install xlrd
```


pipを追加する。改良⇒
```
FROM python:3.11.4
RUN pip install pandas
RUN pip install openpyxl
RUN pip install xlrd
RUN pip install pymysql
```


## MySQLをインストール＆コンテナ作成
・現有Docker内にMySQL(DB)用のコンテナを作成しMySQLをインストールします。
WSLのかわいいアイコンからubuntuを立ち上げて次のコマンド。
```
docker run --name mysql-db -e MYSQL_ROOT_PASSWORD=keiji -d mysql:latest
```
※₁「mysql-db」は任意でコンテナ名をつけましょう。
※₂「keiji」は任意でパスワードを設定します。

新たなコンテナができたか確認
```
docker ps
```

MySQLがインストールされたか確認
```
sudo apt install mysql-client-core-8.0
```
```
mysql --version
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3518951/d296d432-6e9d-9977-89a1-75c56add912c.png)


エラーが出ないように次の作業を行います。
暗号化に関するコマンドを実行してインストール。
https://pypi.org/project/cryptography/
```
pip install cryptography
```



先にMySQLのコンテナにデータベースを作成する必要があります。
MySQLのDBに直接接続
WSLのターミナルから、次のコマンド
```
docker exec -it <コンテナ名またはID> bash
```
ユーザー名の指定で接続
```
mysql -u ユーザー名 -p
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3518951/06026a16-c8ea-a40c-c3c0-2f36bc6eb0e8.png)

既存のデータベース名を一覧表示
```
SHOW DATABASES;
```
デフォルトのデータベースが表示されることを確認

データベースの作成
```
CREATE DATABASE keiji_db;
```
※keiji_dbは任意の名前です。

データベース作成できているか確認
```
SHOW DATABASES;
```
デフォルト以外のデータベースとして追加されていることが分かる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3518951/29ff7180-79ac-c3c6-6d58-f690352c2a2c.png)



## Pythonの実行（VSCodeのアプリケーション側に接続されたターミナル）
コンテナの現状を確認します。
```
docker ps
```

問題なければ、VSCodeの画面からリビルドします。
リビルドできたら、ターミナルで次のコードを実行。
（やり方が分からなければ、前回の記事参照）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3518951/92631639-863e-1007-c029-fe243a3fdd9b.png)
```
python app.py
```


データベースに接続し、Excelからdfを作成し、CSVデータからMySQLのテーブルにレコードが追加されたか確認
まずMySQLクライアントに接続(（WSLのターミナルが立ち上がっている方は省略）
MySQLのDBに直接接続
WSLのターミナルから、次のコマンド
```
docker exec -it <コンテナ名またはID> bash
```
ユーザー名の指定で接続
```
mysql -u ユーザー名 -p
```

データベースに切り替える。
```
USE keiji_db;
```
※keiji_dbは今回作成したデータベース名です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3518951/ddc635b0-5dd4-2195-e06a-61518f755918.png)

テーブルの一覧表示
```
SHOW TABLES;
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3518951/784ba77d-1281-4341-2cff-ae41f623a9fa.png)

テーブルの詳細を表示
```
DESCRIBE テーブル名;
```
私の場合はテーブル名にスペースがあるので、バッククオートで囲みます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3518951/73c1dc29-d372-45da-a282-96771ef2b4ca.png)


SQL文を放り込みます。これでテーブルの中身を確認
```
SELECT * FROM テーブル名;
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3518951/2ea687b1-a00d-73b8-42a6-76a056f87184.png)
これで作業は完了です。

勉強なりますねー。やはり英語の方が安心してレコード追加できる気がします(^^;postgreSQLも確か日本語を織り交ぜるとインポートとか上手くできなかった気がします。

では！