SQLをスレッド実行する！！！

リンクラフトでエンジニアとして働いている河野と申します！
リンクラフトアドベントカレンダーの24日目を担当します！
Pythonで「SQLスレッド実行」というものを現場の業務でやったので、
アウトプットがてら簡単なサンプルコードをご紹介したいと思います！！

各バージョンは以下の通りです！
・macOS Sonoma 14.6.1
・mysql  Ver 9.0.1
・Python 3.9.7
# 環境構築
## 1. mysqlをインストール
### 1-1. Homebrewを使いMySQLをインストールする
```
$ brew install mysql
```
### 1-2. インストールしたMySQLを確認
```
$ brew info mysql
```
### 1-3. MySQLを起動
```
$ mysql.server start
```
### 以下のメッセージが出力されたら成功
```
Starting MySQL
.. SUCCESS! 
```
## その他のコマンド
### 1-4. MySQLの状態を確認
```
$ mysql.server status
```
### 以下のメッセージが表示
```
SUCCESS! MySQL running (1253)
```
### 1-5. MySQLを停止
```
$ mysql.server stop
```
### 以下のメッセージが表示
```
Shutting down MySQL
.. SUCCESS!
```
### 1-6. MySQLをもう一度起動
```
$ mysql.server start
```
### 1-7. 起動中のMySQLで再起動
```
$ mysql.server restart
```
### 以下のメッセージが表示されたら成功
```
Shutting down MySQL
... SUCCESS! 
Starting MySQL
... SUCCESS!
```

## 2. MySQL起動方法
### rootユーザーでログイン
```
$ mysql -u root
```

### ログインできれば成功
```
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 29
Server version: 9.0.1 Homebrew

Copyright (c) 2000, 2024, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> 
```
## 3. データベース準備
### 3-1. データベース作成
```
mysql> CREATE DATABASE testdb;
```
### 3-2. データベース一覧を確認
```
mysql> SHOW DATABASES;
```
### 以下が表示されていれば成功
```
+------------+
| database() |
+------------+
| testdb     |
+------------+
1 row in set (0.00 sec)
```
### 3-3. データベース選択
```
mysql> use testdb
```
### 以下が表示されていれば成功
```
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> 

```
## 4. データ投入
```
CREATE TABLE student (
    studennuber CHAR(5) PRIMARY KEY,
    name VARCHAR(255),
    building VARCHAR(255)
);

INSERT INTO student(studennuber, name, building) VALUES
('Z0001', 'A', '秋葉原'),
('Z0002', 'B', '池袋'),
('Z0003', 'C', '大阪'),
('Z0011', 'D', '大阪'),
('Z0018', 'E', '札幌');
```
### テーブル確認
```
mysql> SHOW TABLES FROM testdb;
```
### 以下が表示されていれば成功
```
+--------------------+
| Tables_in_testdb   |
+--------------------+
| student       |
+--------------------+
1 rows in set (0.01 sec)
```

## 5. pythonでmysqlライブラリ使用方法
### 1. pipコマンドでmysql-connector-pythonライブラリインストール
   ※ 私の環境では--userオプションつけないとエラー吐きましたので注意
```
$ pip install mysql-connector-python --user
```
### pipコマンドが使用できない場合
公式ページのインストール方法に従う
[公式](https://pip.pypa.io/en/stable/installing/)のやり方に従って、以下のcurlコマンドで get-pipというPythonファイルをダウンロードします。

#### 1. curlコマンドでget-pip.pyインストール
```
$ curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
```
ダウンロードしたget-pip.pyを実行するとpipがインストールされます。
#### 2. python3コマンドでget-pip.py実行
```
$ python3 get-pip.py
```
#### 3. pipインストール後はget-pip.py削除
```
$ rm -i get-pip.py
```
# tread.pyを実行
```
$ /usr/local/bin/python3 thread.py
```
```tread.py
import mysql.connector
import threading

# DB接続コネクション
conn = mysql.connector.connect(
	host='127.0.0.1',
	db='testdb',
	user='root',
	password='パスワード'
)

"""SQLスレッド実行を行う
:args conn: DB接続コネクション i: スレッドカウンタ
"""
def query_worker(conn, i):
	with conn.cursor() as cur:
		# SQLを実行
		sql = "select * from student"
		cur.execute(sql)

		# 実行結果を取得
		rows = cur.fetchall()

		# 1行ずつ表示
		print(f"tread{i + 1}回目")
		for row in rows:
			print(row)

	cur.close()

# スレッドごとにSQLを実行
threads = []
for i in range(5):
	t = threading.Thread(target=query_worker, args=(conn, i))
	threads.append(t)
	# スレッド開始
	t.start()
	# スレッドの終了を待つ
	t.join()

```

## 実行結果
スレッドごとにSQL実行結果が取得できれば成功です！
```
tread1回目
('Z0001', 'A', '秋葉原')
('Z0002', 'B', '池袋')
('Z0003', 'C', '大阪')
('Z0011', 'D', '大阪')
('Z0018', 'E', '札幌')
tread2回目
('Z0001', 'A', '秋葉原')
('Z0002', 'B', '池袋')
('Z0003', 'C', '大阪')
('Z0011', 'D', '大阪')
('Z0018', 'E', '札幌')
tread3回目
('Z0001', 'A', '秋葉原')
('Z0002', 'B', '池袋')
('Z0003', 'C', '大阪')
('Z0011', 'D', '大阪')
('Z0018', 'E', '札幌')
tread4回目
('Z0001', 'A', '秋葉原')
('Z0002', 'B', '池袋')
('Z0003', 'C', '大阪')
('Z0011', 'D', '大阪')
('Z0018', 'E', '札幌')
tread5回目
('Z0001', 'A', '秋葉原')
('Z0002', 'B', '池袋')
('Z0003', 'C', '大阪')
('Z0011', 'D', '大阪')
('Z0018', 'E', '札幌')
```

一緒に働く仲間を募集中です！

リンクラフト株式会社では、組織拡大に伴い積極的な採用活動を行っています。
少しでも興味がある方はぜひご連絡ください。

▽会社ホームページ
https://lincraft.co.jp/
▽Instagram
https://www.instagram.com/lincraft.inc/
▽ご応募はこちらより
https://lincraft.co.jp/recruit

※カジュアル面談も受付中です。ご希望の方はHPのお問い合わせフォームよりご連絡ください。