3
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【Python】0からWebアプリ!ハンズオン(4)~データ成形編~

Posted at

概要

Pythonで0からWebアプリを作る機会があったので、そのまとめとして!
この記事ではデータベースから取得したデータの成形について書いています。
APIから返却されるデータに統一性がないと、フロントエンドエンジニアさんたちは困ってしまいます!
なので、今回はjsonというデータ形式に統一してデータを返す方法を説明します!

これまでの記事
【Python】0からWebアプリ!ハンズオン(0)~環境構築編~ - Qiita
【Python】0からWebアプリ!ハンズオン(1)~設計、DB構築編~ - Qiita
【Python】0からWebアプリ!ハンズオン(2)~ハローワールド編~ - Qiita
【Python】0からWebアプリ!ハンズオン(3)~API実装編~ - Qiita

こんな方に読んでほしい

  • プログラミング未経験だけどアプリ作ってみたい方
  • 新人Webプログラマの方
  • 経験者だけどPythonでWebアプリ書いたことない方

ゴール

HTML, CSS, JavaScript, Python, SQLを使ってCURD機能を持ったWebアプリを作成するのが目標です。

必要なもの

  • PC(Windows OS)
  • インターネット回線
  • わくわくした気持ち

1. フォルダ構成

今回作成するフォルダ、ファイルは以下の通りです。

todo/
 └ api/
  ├ index.py
  └ Todo.py

2. データベースから取得したデータをクラスオブジェクトに変換する

まずはデータベースから取得したデータをプログラム上で扱いやすくするために、クラスオブジェクトに変換します。
Python3.7以降はdataclassesという機能があり、クラスの定義が楽になりました。
dataclasses --- データクラス — Python 3.8.5 ドキュメント

まず、コマンドプロンプト上で以下のコマンドを実行します。

cmd
pip install dataclasses

続いて、apiフォルダ配下に新しくTodo.pyというファイルを作成してください。

Todo.py
from dataclasses import dataclass

@dataclass
class Todo:
    id: str
    title: str
    created: str
    is_deleted: str

そしてindex.pyを修正します。

index.py
# -*- coding:utf-8 -*-

# 外部のパッケージを読み込む
from bottle import route, run
import psycopg2
from Todo import Todo # 上で作成したTodoクラスの読み込みを追加

# データベースへの接続を取得する
def get_connection():
    return psycopg2.connect("host=localhost port=5432 dbname=TodoDatabase user=postgres password=postgres")

# Todoデータを取得
@route('/todos')
def get_todos():
    # データベースとの接続を確立
    with get_connection() as conn:
        # カーソルを生成
        with conn.cursor() as cur:
            # SQLを実行
            cur.execute('SELECT * FROM todo')
            
            # データベースへの問い合わせ結果を1件取得
            data = cur.fetchone()
            
            # DBから取得したデータをクラスオブジェクトに変換(Todoクラスのインスタンス生成)して返却
            todo = Todo(data[0], data[1], data[2], data[3])
            return str(todo)


# Webサーバーの実行構成
# URLの "http://[host]:[port]/[route]" の構成となる
run(host='localhost', port=8080, debug=True)

コマンドプロンプト上でアプリのルートフォルダに移動し、python index.pyを実行してサーバーを起動し、ブラウザで http://localhost:8080/todos にアクセスすると以下のようなデータが表示されると思います。
2020-08-28_10h47_51.png

2. クラスオブジェクトをjson形式に変換する

それでは本題のjson形式に変換してみましょう。

dataclassesで生成したクラスはdataclasses_jsonを使用することで簡単にjson形式に変換することができます。
GitHub - lidatong/dataclasses-json: Easily serialize Data Classes to and from JSON

コマンドプロンプト上で以下のコマンドを実行します。

pip install dataclasses-json

Todo.pyを編集します。
dataclasses_jsonを追加でインポートし、dataclass_jsonアノテーションを追加します。

Todo.py
from dataclasses import dataclass
from dataclasses_json import dataclass_json # 追加

@dataclass_json # 追加
@dataclass
class Todo:
    id: str
    title: str
    created: str
    is_deleted: str

そしてindex.pyを以下のように編集します。

index.py
# -*- coding:utf-8 -*-

# 外部のパッケージを読み込む
from bottle import route, run, response # response追加
import psycopg2
from Todo import Todo
import json # 追加

# データベースへの接続を取得する
def get_connection():
    return psycopg2.connect("host=localhost port=5432 dbname=TodoDatabase user=postgres password=postgres")

# Todoデータを取得
@route('/todos')
def get_todos():
    # レスポンスのデータ形式をjsonに変更
    response.headers['Content-Type'] = 'application/json'
    response.headers['Cache-Control'] = 'no-cache'

    # データベースとの接続を確立
    with get_connection() as conn:
        # カーソルを生成
        with conn.cursor() as cur:
            # SQLを実行
            cur.execute('SELECT * FROM todo')
            
            # データベースへの問い合わせ結果を1件取得
            data = cur.fetchone()

            # DBから取得したデータをjsonに変換して返却
            # 作成日時(data[2])は文字列型にキャストする
            # "ensure_ascii=False"を指定しないと、非ASCII文字が "\uXXXX" の形にエスケープされるので、日本語が返却できない
            # データベースのデータをクラス(Todo())→辞書型(.__dict__)→json(json.dumps)に変換する必要がある
            todo = Todo(data[0], data[1], str(data[2]), data[3])
            return json.dumps(todo.__dict__, ensure_ascii=False)

# Webサーバーの実行構成
# URLの "http://[host]:[port]/[route]" の構成となる
run(host='localhost', port=8080, debug=True)

再度python index.pyを実行してサーバーを起動し、ブラウザで http://localhost:8080/todos にアクセスすると、こんな形で返ってくるようになりました!
2020-08-28_11h34_40.png
このようにデータひとつひとつがkey-valueのセットになって返ってくることで、フロントエンドで非常に扱いやすくなりました。
また、フロントエンドエンジニアからAPIの仕様書を求められたときも非常に書きやすいのです!

おまけ

ちなみにブラウザはGoogle Chromeで動作確認していますが、json形式のデータをフォーマットしてくれる拡張機能を入れています。
色付けしてくれたり、パネルの開閉ができたりして便利なのでぜひお試しあれ!
JSON Formatter - Chrome ウェブストア

まとめ

データベースのデータをjson形式で返してくれるRest APIの実装を行いました!

次回は・・・

今まではURLを直接入力してAPIにアクセスしていましたが、そろそろページを作っていきたいものです。
次回はHTMLを作成してJavaScriptのコードからアクセスしてみます!

3
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?