Help us understand the problem. What is going on with this article?

Flask を用いたデータベースアプリケーション制作 Part2

環境

macOS Catalina 10.15.1

アプリケーションの実装内容

Flask の使い方を習得すべく3つのパートに分けた。

Part1(前稿)

  • Web ブラウザの表示
  • Templates フォルダの html ファイルと連結

Part2(本稿)

  • データベース SQLite との連結
  • Bootstrap を用いた画面表示

Part3(次稿)

  • POSTメソッドを用いた新規ユーザー登録

Part2のフォルダ構成

Part1と同様に、全てのコードは run.py によって実行される。
run.py は Part1 と同じコードを使用した。

root
|--codes
| |--view.py
| |--templates
| | |--index2.html
|--models.py
|--run.py
|--test.db

データベース SQLite との連結

view.py を以下に示す。
view.py 外部のデータベースに登録されている値を model.py の User クラスで定義することで連結している。

view.py
# SQLAlchemy はデータベース(DB)を object のように扱えるライブラリである。
# 今回は DB との連結を担当する。
# models.py の User クラスで、どのような object として扱うかを決める。
from flask import Flask,render_template
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker 
from models import User

app = Flask(__name__)

# test.db (DB) と連結するための object である engine を作り、DB を session に代入する。
engine = create_engine('sqlite:///test.db')
session = sessionmaker(bind=engine)()

# /index2 へアクセスがあった場合に、 index2.html を返す。
@app.route("/index2")

# index2 関数を定義する。
# sessionn の全データを、User クラスで定義された object に代入し、users として返す。
# この users を html 内の users に代入する。

def index2():
    users = session.query(User).all()
    return render_template('index2.html', users=users)

if __name__ == "__main__":
    app.run(debug=True)

SGLite によるデータベース構築

データベース管理システム sqlite で次の test.db を作成する。sqlite は、MAC にはデフォルトでインストールされている。

id name age
0 Yoshizaki 27
1 Kikagaku 2

まず次のコマンドを実施する。test.db が DB の名前である。

ターミナル
sqlite3 test.db

するとsqlite>という prefix が付与された対話モードに切り替わる。ここでは、DB の中に table を作ることができる。
まず id, name, age という3つの column からなる table を作る。

ターミナル
create table users(id integer primary key autoincrement, name text, age integer);

そして id = 0, id = 1 の要素を順番に挿入していく。

ターミナル
insert into users(name, age) values('Yoshizaki', 27);
insert into users(name, age) values('Kikagaku', 2);

select コマンドで DB を確認する。

ターミナル
select * from users;

その結果

ターミナル
1|Yoshizaki|27
2|Kikagaku|2

と出力されれば、正しく DB は作られている。対話モードからは .exit で抜けられる。

データベースモデルの定義

データベース(DB)の中身をどのような object で定義するかを以下の model.py で決める。これも SQLAlchemy ライブラリで可能である。

model.py
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String
Base = declarative_base()
class User(Base):
    __tablename__='users'

    id = Column(Integer, primary_key = True)
    name = Column(String)
    age = Column(Integer)

SQLite の primary key に id を採用したため、モデルでも同様に指定している。

ブラウザへの表示

index2.html は以下のとおり。(後で編集する。)

index2.html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content = "width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <hl>Flask チュートリアル</hl>
    {% for user in users %}
        <p>名前: {{user.name}}</p>
    {% endfor %}
</body>
</html>

Part1 と同様に http://127.0.0.1:5000/index2 にアクセスして以下が表示されていれば成功である。

Flask チュートリアル
名前: Yoshizaki

名前: Kikagaku

Bootstrap を用いて編集

CSS (cascading style sheets) のフレームワークである Bootstrap を使って index2.html を以下のように書き換える。
Bootstrap はよく使用されるスタイルが予め定義されており便利である。コードはこちらから引用した。

index2.html
d<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content = "width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <!-- Bootstrap -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
    <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
</head>
<body>
    <div class="container">
        <div class="row">
            <hl>Flask チュートリアル</hl>
            <table class="table table-striped table-hover">
                <thread>
                    <tr>
                        <th scope="col">#</th>
                        <th scope="col">Name</th>
                        <th scope="col">Age</th>
                    </tr>
                </thread>
                <tbody>
                    {% for user in users %}
                        <tr>
                            <td>{{user.id}}</td>
                            <td>{{user.name}}</td>
                            <td>{{user.age}}</td>
                        </tr>
                    {% endfor %}
                </tbody>
            </table>
        </div>
    </div>
</body>
</html>

同様に、http://127.0.0.1:5000/index2 にアクセスして以下が表示されていれば成功である。

Sg0U7US.png

参考

データ収集からWebアプリ開発まで実践で学ぶ機械学習活用ガイド の chapter 3-4-1 および chapter 3-5

keisuke-ota
北海道大学大学院修士1年/ 腸内細菌叢や腸内細菌代謝物の多変量解析を専門に取り組んでおります。 ご質問等がございましたら、お気軽にご連絡ください。
https://altair.sci.hokudai.ac.jp/infmcb/index.html
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away