[学習メモ]エンジニア探検隊#2 -DBを立ててみる-

# 第二話　DBを立てる
  - 著者:[takaryo1010](https://github.com/takaryo1010)
  - 協力者:[fukuchy](https://github.com/fukuchy)
  - ここでは、私と、協力者の学習のためのメモを残していきます。ほかの人の学習の助けになれば幸いです。
  - 作るもの：ゲームの結果をデータベース上に保存したい
  - 使用言語：`Python`
  - 必要ナレッジ
      - データベース(DB)とは
      - `Docker`について
      - `MySQL`について
  ## やったこと
### 1. Docker、DBの準備
- 使用したもの(Wikiのリンク)
    - [`Docker`](https://ja.wikipedia.org/wiki/Docker)
    - [`MySQL`](https://ja.wikipedia.org/wiki/MySQL)
     
https://www.youtube.com/watch?v=B5tSZr_QqXw&t=1067s

これを主軸にただただ進めてった...

```
docker run --name name-mysql -p 13306:3306 -e MYSQL_ROOT_PASSWORD=password -d mysql
```
```
docker exec -it name-mysql bash
```
```
mysql -u root -p   (ここでpasswordが求められる)
```
```
CREATE DATABASE name_db;
```
```
USE name_db;
```
```
CREATE TABLE scores(name varchar(50),score int);
```
#### メモ
VMwareでDockerを立てると、host当たりがうまくかみ合わなくてできんかった。
name-sql、name_db、passwordは適宜好きな文字列を入れる。
今回は
name-sql = shooting-sql
name_db  = shooting_db
password = shooting


### 2. DBとAPIをくっつける。
以下そのコード
#### API側のコード
```API.py
from flask import Flask, jsonify,request
import csv
import mysql.connector,json
app = Flask(__name__)

def select_to_json(table):
        sql = (f'INSERT INTO {table}(name, score) values (%s, %s)')
        cursor.execute('select * from shooting_db.scores')
        data =  cursor.fetchall()
        records = []
        for row in data:
            record = {'name': row[0], 'score': row[1]}
            records.append(record)
        records = sorted(records, key=lambda x: x['score'], reverse=True)[:10]
        cursor.execute('delete from shooting_db.scores')
        for record in records:
            cursor.execute(sql, (record['name'], record['score']))  
        
        return json.dumps(records, indent=4)

cnx = mysql.connector.connect(
    user = 'root',
    password ='shooting',
    host = '127.0.0.1',
    port = '13306',
    database = 'shooting_db'
)   

cursor = cnx.cursor()

@app.route('/', methods=["GET","POST"])
def getandpost():
    if request.method == "GET":
        table = "scores"
        return select_to_json(table)
    
    elif request.method == "POST":
        table = "scores"
        name = request.json["name"]
        score = request.json["score"]
        sql = (f'INSERT INTO {table}(name, score) values (%s, %s)')

        cursor.execute(sql, (name, score))
        cnx.commit()
        cursor.execute('select * from shooting_db.scores')
        data =  cursor.fetchall()
        cursor.execute('truncate table shooting_db.scores')
        
        records = []
        for row in data:
            record = {
                'name': row[0],
                'score': row[1]
                }
            records.append(record)
        records = sorted(records, key=lambda x: x['score'], reverse=True)[:10]
        
        for record in records:
            cursor.execute(sql, (record['name'], record['score']))
        cnx.commit()
        return select_to_json(table)
...




if __name__ == "__main__":
    app.run(host='127.0.0.1', port=8888, debug=True)


```
#### リクエスト(POST)する側のコード　
>[前回とあんまりかわんないかも](https://qiita.com/takaryo1010/items/ca0df80b8aa6964788d8)
```request.py
import requests

POST_URL = "http://localhost:8888"

name = input("name:")
score = input("score:")


request_body = {"name":name,"score":score}

res = requests.post(POST_URL,json=request_body)
#res = requests.get(POST_URL)
print("--------------------")
print(res.text)
print("--------------------")
```

#### 出力結果
<details><summary>長いので畳んでます</summary>

```
[
    {
        "name": "takaryo",
        "score": 9999
    },
    {
        "name": "takaryo",
        "score": 9999
    },
    {
        "name": "takaryo",
        "score": 9999
    },
    {
        "name": "takaryo",
        "score": 9999
    },
    {
        "name": "Fukuchy",
        "score": 8888
    },
    {
        "name": "sad",
        "score": 123
    },
    {
        "name": "da",
        "score": 123
    },
    {
        "name": "efds",
        "score": 34
    },
    {
        "name": "asd",
        "score": 12
    },
    {
        "name": "asda",
        "score": 123
    }
]
```

</details>

## 感想
- Doclkerの理解がかなり浅い。
    - hostとかその辺が分かってない。
    - ネット上に公開するには、このDockerをサーバーにデプロイするの...?
- MySQLを触り始めるので、SQLを書けるようになりたい。
    - 今回使ってみたやつ
        - `SELECT`
        - `INSERT`
        - `TRUNCATE`
- DBの内容が簡易なもの(テーブルをまたいで、つまり関係づけてない)のため、DBの上手な利用にはなっていない。
    - DB設計などの学習をする。
- jsonでPOSTの結果を受け取れるようになったため、ゲームに実際に組み込んでみる。