5. WebでのリクエストURLによる処理の振り分け(PythonのFlaskを使用)

この演習では,Webサーバとデータベースの連携について説明する.前回の授業で扱ったMySQL Employees Sampleデータベースを使用する.

Webサーバ

Webサーバは,Webブラウザ等からの要求に対して,返答を返す.返答はHTMLであったり,他のオブジェクトであったりする.

Webサーバのポート番号

Webサーバの起動時には,通信に使うポート番号を指定できる.この演習では,ポート番号8080を指定する.

リクエストのルーティング

Webサーバに送られたURLに応じて処理を変えたいとする.例えば,Webブラウザで「http://localhost/db」としたときには「welcome」を,「http://localhost/db/hoge」としたときには「hoge」を表示したいとする.

このとき,次のようなプログラムを書く.

# -*- coding: utf-8 -*-

from flask import Flask

app = Flask(__name__)

@app.route('/db')
def tables():
    return 'welcome'

@app.route('/db/hoge')
def hoge():
    return 'hoge'

app.run(host='localhost', port=8080, debug=True)

■ SQLite3でのテーブル一覧取得

SQLite3でテーブル一覧を取得したいときは,次のようなSQL文を書く.

SELECT name FROM sqlite_master WHERE type='table';

演習準備

この演習では Python を使用する。Python がインストールされていない場合は,下記の「Python 3.12 のインストール(Windows 上)」を展開し,手順に従いインストールすること。下記の「必要なライブラリのインストール」を実施すること。

Python 3.12 のインストール(Windows 上) [クリックして展開]

以下のいずれかの方法で Python 3.12 をインストールする。Python がインストール済みの場合、この手順は不要である。

方法1:winget によるインストール

管理者権限コマンドプロンプトで以下を実行する。管理者権限のコマンドプロンプトを起動するには、Windows キーまたはスタートメニューから「cmd」と入力し、表示された「コマンドプロンプト」を右クリックして「管理者として実行」を選択する。

winget install --id Python.Python.3.12 -e --scope machine --silent --accept-source-agreements --accept-package-agreements --override "/quiet InstallAllUsers=1 PrependPath=1 Include_test=0 Include_pip=1 Include_launcher=1 InstallLauncherAllUsers=1 TargetDir=\"C:\Program Files\Python312\""
powershell -Command "$p='C:\Program Files\Python312'; $s=\"$p\Scripts\"; $m=[Environment]::GetEnvironmentVariable('Path','Machine'); if($m -notlike \"*$s*\") { [Environment]::SetEnvironmentVariable('Path', \"$p;$s;$m\", 'Machine') }"

--scope machine を指定することで、システム全体(全ユーザー向け)にインストールされる。このオプションの実行には管理者権限が必要である。インストール完了後、コマンドプロンプトを再起動すると PATH が自動的に設定される。

方法2:インストーラーによるインストール

  1. Python 公式サイト(https://www.python.org/downloads/)にアクセスし、「Download Python 3.x.x」ボタンから Windows 用インストーラーをダウンロードする。
  2. ダウンロードしたインストーラーを実行する。
  3. 初期画面の下部に表示される「Add python.exe to PATH」に必ずチェックを入れてから「Customize installation」を選択する。このチェックを入れ忘れると、コマンドプロンプトから python コマンドを実行できない。
  4. 「Install Python 3.xx for all users」にチェックを入れ、「Install」をクリックする。

インストールの確認

コマンドプロンプトで以下を実行する。

python --version

バージョン番号(例:Python 3.12.x)が表示されればインストール成功である。「'python' は、内部コマンドまたは外部コマンドとして認識されていません。」と表示される場合は、インストールが正常に完了していない。

演習

Employees Sample データベース(SQLite版)

このデータベースは,MySQL Employees Sample Database を SQLite 形式に変換したものであり,GitHub 上の bytebase/employee-sample-database リポジトリで公開されている。出典と著作権表示は以下のとおりである。

データの出典: MySQL Employees Sample Database(原著者: Fusheng Wang, Carlo Zaniolo。リレーショナルスキーマ: Giuseppe Maxia。データ変換: Patrick Crews)

This work is licensed under the Creative Commons Attribution-Share Alike 3.0 Unported License. To view a copy of this license, visit http://creativecommons.org/licenses/by-sa/3.0/ or send a letter to Creative Commons, 171 Second Street, Suite 300, San Francisco, California, 94105, USA.

SQLite adaptation: bytebase/employee-sample-database (MIT License)

ステップ1:Employees Sample データベースのダウンロード

以下の手順で,Employees Sample データベース(SQLite版)をダウンロードする。

このデータベースは,MySQL Employees Sample Database を SQLite 形式に変換したものであり,GitHub 上の bytebase/employee-sample-database リポジトリで公開されている。

コマンドプロンプトで以下のコマンドを実行し,データベースファイルをカレントディレクトリにダウンロードする。python -c は,引用符内の Python コードをコマンドライン上で直接実行するオプションである。urllib.request.urlretrieve は,第1引数に指定した URL からファイルを取得し,第2引数に指定したファイル名で保存する関数である。

python -c "import urllib.request; urllib.request.urlretrieve('https://raw.githubusercontent.com/bytebase/employee-sample-database/main/sqlite/dataset_small/employee.db', 'employee.db')"

■ ステップ2

  1. メモ帳を起動する.
  2. コマンドプロンプトで以下を実行する。コマンドプロンプトを起動するには、Windows キーまたはスタートメニューから「cmd」と入力する。

    notepad a.py
    
  3. メモ帳で次のプログラムを記述する.
  4. from flask import Flask
    
    app = Flask(__name__)
    
    @app.route('/db')
    def tables():
        return 'welcome'
    
    app.run(host='localhost', port=8080, debug=True)
    
  5. ファイルを保存する(メモ帳で、「ファイル」、「保存」)。
  6. 実行する.
  7. 保存したファイル名は a.py であり、次のように操作する。

    python a.py
    
  8. Webブラウザを開き,http://localhost:8080/db を指定するとwelcomeと表示される.

※ Windowsでうまく動かない場合

ファイアウォールが設定されている可能性がある.次の手順で,ポート番号8080に関するファイアウォールを解除してみる.

■ ステップ3

  1. メモ帳でファイルを次のように書き換えて保存する(メモ帳で、「ファイル」、「保存」)。
  2. from flask import Flask
    
    app = Flask(__name__)
    
    @app.route('/db')
    def tables():
        return 'hoge'
    
    app.run(host='localhost', port=8080, debug=True)
    
  3. Webブラウザで,http://localhost:8080/db を指定すると,今度は,hogeと表示される.

■ ステップ4

  1. メモ帳でファイルを次のように書き換えて保存する(メモ帳で、「ファイル」、「保存」)。
  2. from flask import Flask
    import sqlite3
    import pandas
    
    app = Flask(__name__)
    DB = 'employee.db'
    
    def query(sql):
        with sqlite3.connect(DB) as c:
            return pandas.read_sql(sql, c)
    
    @app.route('/db')
    def tables():
        df = query("SELECT * FROM sqlite_master WHERE type='table';")
        return '<pre>%s</pre>' % df.to_string()
    
    if __name__ == '__main__':
        app.run(host='localhost', port=8080, debug=True)
    
  3. Webブラウザを開き,http://localhost:8080/db を指定するとテーブル一覧が表示される.

■ ステップ5

  1. メモ帳でファイルを次のように書き換えて保存する(メモ帳で、「ファイル」、「保存」)。
  2. from flask import Flask
    import sqlite3
    import pandas
    
    app = Flask(__name__)
    DB = 'employee.db'
    
    def query(sql):
        with sqlite3.connect(DB) as c:
            return pandas.read_sql(sql, c)
    
    @app.route('/db')
    def tables():
        df = query("SELECT * FROM sqlite_master WHERE type='table';")
        return '<pre>%s</pre>' % df.to_string()
    
    @app.route('/db/departments')
    def departments():
        df = query("SELECT * FROM department;")
        return '<pre>%s</pre>' % df.to_string()
    
    if __name__ == '__main__':
        app.run(host='localhost', port=8080, debug=True)
    
  3. Webブラウザを開き,http://localhost:8080/db/departments を指定するとデータが表示される.