Fast APIでWebAPIを作ってみる②

## FastAPIを利用してWebAPIを作っていくシリーズの2回目です。

### 今回と次回で、前回作ったWebAPIに、DATABASEへのアクセス機能を追加していきます。<br>少し長くなるので、Docker上にpostgresを構築する方法と、FastAPIからPostgresへのアクセス方法の2回に分けてみます。
前回作ったWebAPIの記事へのアクセスは以下。<br>[Fast APIでWebAPIを作ってみる①](https://qiita.com/AQUA651/items/d130132493d6b2ad0bd7)

## 開発環境
　　|バージョン
---|---
Python|3.10.4
FastAPI|0.78.0
Uvicorn|0.18.1
Docker|20.10.16
postgresql　<font color="Red">追加</font>|14.4


## 今回のお題
今回は
　①docker-composeの修正
　②DB、テーブルの作成／データ挿入SQLの作成
　③dockerの動作検証

辺りまでを実装していきます。

## 実装
### フォルダ構成は以下の通りです。
```フォルダ構成.
┣━backend/
┃　　┣━app
┃　　┃　┣━api
┃　　┃　┃　┗━routes
┃　　┃　┗━core
┃　　┣━Dockerfile
┃　　┗━requirements.txt
┣━script　　　　　　　　　　　　# 追加
┗━docker-compose.yml
```


### ①docker-composeの修正
先ずは、docker-compose.ymlの修正となります。
ymlファイルの「service」タグ内に以下のコードを追加します。
```docker-compose.yml
# Postgresql 
################### 以下追加　###################
  db:
    image: postgres:14.4-alpine
    container_name: postgres_test

    # image作成時の初期設定の値を設定する
    environment:  
        ENV LANG: ja_JP.UTF-8        # postgres内の文字コードを指定
        TZ: Asia/Tokyo               # postgres内のTimeZoneを指定
        POSTGRES_DB: Incident
        POSTGRES_PASSWORD: postgrespw
    # Postgresに接続するためのポート（外部からのアクセス時のポート：docker内部からのアクセス時のポート）
    ports: 
        - "5436:5436"
    volumes:
      - ./script:/docker-entrypoint-initdb.d    # 追加(scriptフォルダ内にあるスクリプトを実行する。)
      - db-store:/var/lib/postgresql/data       # DBデータ永続化

# DBデータ永続化
volumes:
  db-store:
```

### ②DB、テーブルの作成／データ挿入SQLの作成
以下で作成するsqlファイルは、今回作成した「script」フォルダ内に作成します。

Databaseの作成
```01_initialize.sql
-- DB作成
CREATE DATABASE Incident; 

-- 作成したDBへ切り替え
\c Incident
```
MA_CODEのテーブル作成
````02_create_table_ma_code.sql
-- テーブル作成
CREATE TABLE MA_CODE(
    id serial primary key,
    code_1 varchar(4) NOT NULL,
    code_2 varchar(2) NOT NULL,
    code_nm_1 varchar(50) NOT NULL,
    code_nm_2 varchar(50) NOT NULL,
    Active_flg boolean NOT NULL,
    created_by varchar(8) NOT NULL,
    created_date timestamp NOT NULL,
    updated_by varchar(8) NOT NULL,
    updated_date timestamp NOT NULL,
    update_counter integer NOT NULL
)
````
作成したテーブル内にデータを挿入するためのSQL
```99_Insert_data.sql
INSERT INTO MA_CODE VALUES(1,'0100','01','状態区分','作成中','TRUE','AQUA651','2022/07/01 00:00:00','AQUA651','2022/07/01 00:00:00',1);
INSERT INTO MA_CODE VALUES(2,'0100','02','状態区分','申請中','TRUE','AQUA651','2022/07/01 00:00:00','AQUA651','2022/07/01 00:00:00',1);
INSERT INTO MA_CODE VALUES(3,'0100','03','状態区分','受付中','TRUE','AQUA651','2022/07/01 00:00:00','AQUA651','2022/07/01 00:00:00',1);
INSERT INTO MA_CODE VALUES(4,'0100','04','状態区分','対応中','TRUE','AQUA651','2022/07/01 00:00:00','AQUA651','2022/07/01 00:00:00',1);
INSERT INTO MA_CODE VALUES(5,'0100','05','状態区分','確認中','TRUE','AQUA651','2022/07/01 00:00:00','AQUA651','2022/07/01 00:00:00',1);
```
### ③dockerの動作検証
ここまで出来たら、一度、dockerを起動させて、DB,テーブルが作成され、データが挿入されていることを確認します。
````
$ docker-compose build
$ docker-compose up
````
以下の内容が表示されたら、正常に起動したこととなります。
```
postgres_test | PostgreSQL init process complete; ready for start up.
postgres_test |
postgres_test | 2022-07-02 11:12:49.858 JST [1] LOG:  starting PostgreSQL 14.4 on x86_64-pc-linux-musl, compiled by gcc (Alpine 11.2.1_git20220219) 11.2.1 20220219, 64-bit
postgres_test | 2022-07-02 11:12:49.858 JST [1] LOG:  listening on IPv4 address "0.0.0.0", port 5432
postgres_test | 2022-07-02 11:12:49.858 JST [1] LOG:  listening on IPv6 address "::", port 5432
postgres_test | 2022-07-02 11:12:49.864 JST [1] LOG:  listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
postgres_test | 2022-07-02 11:12:49.871 JST [57] LOG:  database system was shut down at 2022-07-02 11:12:49 JST
postgres_test | 2022-07-02 11:12:49.878 JST [1] LOG:  database system is ready to accept connections
```
以下のコマンドを利用して、作成したdockerにアクセスします。
```
$ docker exec -it <作成したコンテナ名> bash
```
コンテナにアクセス出来たら、以下のコマンドで作成したDBにアクセスします。
```
$ psql -U postgres -d Incident
```
\dtコマンドを利用して、Incidentデータベース内のテーブル一覧を表示します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/196226/488014ef-1f08-7da4-ece2-f07cd00e0fb5.png)
MA_CODEが作成されていることが確認できました。

次に、SELECT文を入力して、MA_CODE内にデータが挿入されていることを確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/196226/a3fa132b-0238-b2b3-9c09-c9345a4cd6d6.png)
正常にデータが挿入されていることが確認できました。

これで、下準備は完了となります。

今回はここで終了となります。
次回は、やっとFastAPIの実装について記載していきます。


## 参考にしたサイト
https://nmomos.com/tips/2021/01/23/fastapi-docker-1/
https://fastapi.tiangolo.com/ja/