このシリーズの目的
- PythonのフレームワークであるFlaskを使用してWebアプリに必要な機能の作成と解説をやります。
- 普段の勉強のアウトプットとして書いています。質問や指摘は大歓迎です。
前回まで
PythonのフレームワークFlaskを使用してWebアプリ作成の物語(1)こんにちは世界
PythonのフレームワークFlaskを使用してWebアプリ作成の物語(2)HTMLの表示とメソッドとパラメータの受け取りかた
PythonのフレームワークFlaskを使用してWebアプリ作成の物語(3)Docker登場 DBの準備
目的
- Flask で Postgresql に接続
- DB にレコードを登録できること
- DB からレコードを取得できること
ソースコード
環境準備
python のパッケージを追加
flask
sqlalchemy
psycopg2
上記をpip install -r requirements.txt
でインストール
ポイント
sqlalchemyは python の ORM ライブラリ(簡単に言うとDB 操作は sqlalchemy が担当するよ)
psycopg2
は flask と postgresql を繋いでくれる役割
インストールしたパッケージを一括でアンインストールする(必要があれば)
- pip でインストールしたパッケージの一覧を取得
$ pip freeze > piplist.txt
- 一括でアンインストール
$ pip uninstall -y -r piplist.txt
フォルダ構成
.
├── README.md
├── docker-compose.yml
├── form.html
├── postgresql
│ └── init
│ ├── 1_create_db.sql
│ └── 2_create_table.sh
├── requirements.txt
├── src
│ ├── UserModel.py
│ ├── main.py
│ ├── setting.py
│ └── templates
│ └── hello.html
└── test.http
DB接続の準備
setting.py
from sqlalchemy import *
from sqlalchemy.orm import *
from sqlalchemy.ext.declarative import declarative_base
import psycopg2
# postgresqlのDBの設定
DATABASE = "postgresql://postgres:@192.168.1.19:5432/flask_tutorial"
# Engineの作成
ENGINE = create_engine(
DATABASE,
encoding="utf-8",
# TrueにするとSQLが実行される度に出力される
echo=True
)
# Sessionの作成
session = scoped_session(
# ORM実行時の設定。自動コミットするか、自動反映するなど。
sessionmaker(
autocommit=False,
autoflush=False,
bind=ENGINE
)
)
# modelで使用する
Base = declarative_base()
Base.query = session.query_property()
ポイント
-
DB の接続先情報
DATABASE = "postgresql://postgres:@192.168.1.19:5432/flask_tutorial
DATABASE = "postgresql://{DBのユーザ}:{DBのパスワード}@{url}:{ポート番号}/{DB名}
今回のDBは前回用意したDBをそのまま利用
{url}は自分のPCのIPを入力
-
Engine 作成
ENGINE = create_engine(
DATABASE,
encoding="utf-8",
# TrueにするとSQLが実行される度に出力される
echo=True
)
インストールしたパッケージを一括でアンインストールする(必要があれば)
- pip でインストールしたパッケージの一覧を取得
$ pip freeze > piplist.txt
- 一括でアンインストール
$ pip uninstall -y -r piplist.txt
.
├── README.md
├── docker-compose.yml
├── form.html
├── postgresql
│ └── init
│ ├── 1_create_db.sql
│ └── 2_create_table.sh
├── requirements.txt
├── src
│ ├── UserModel.py
│ ├── main.py
│ ├── setting.py
│ └── templates
│ └── hello.html
└── test.http
from sqlalchemy import *
from sqlalchemy.orm import *
from sqlalchemy.ext.declarative import declarative_base
import psycopg2
# postgresqlのDBの設定
DATABASE = "postgresql://postgres:@192.168.1.19:5432/flask_tutorial"
# Engineの作成
ENGINE = create_engine(
DATABASE,
encoding="utf-8",
# TrueにするとSQLが実行される度に出力される
echo=True
)
# Sessionの作成
session = scoped_session(
# ORM実行時の設定。自動コミットするか、自動反映するなど。
sessionmaker(
autocommit=False,
autoflush=False,
bind=ENGINE
)
)
# modelで使用する
Base = declarative_base()
Base.query = session.query_property()
DB の接続先情報
DATABASE = "postgresql://postgres:@192.168.1.19:5432/flask_tutorial
DATABASE = "postgresql://{DBのユーザ}:{DBのパスワード}@{url}:{ポート番号}/{DB名}
今回のDBは前回用意したDBをそのまま利用
{url}は自分のPCのIPを入力
Engine 作成
ENGINE = create_engine(
DATABASE,
encoding="utf-8",
# TrueにするとSQLが実行される度に出力される
echo=True
)
Engine はDBにアクセスするための土台なんだと覚えとけば、とりあえずOK
- Session作成
session = scoped_session(
# ORM実行時の設定。自動コミットするか、自動反映するなど。
sessionmaker(
autocommit=False,
autoflush=False,
bind=ENGINE
)
)
SessionはflaskとDBとのやり取りを全て担当してくれるもの
データを挿入するテーブルを準備
#!/bin/bash
psql -U postgres -d flask_tutorial << "EOSQL"
CREATE TABLE users (
id SERIAL NOT NULL,
name VARCHAR(200),
created_at TIMESTAMP WITHOUT TIME ZONE NOT NULL,
updated_at TIMESTAMP WITHOUT TIME ZONE NOT NULL,
PRIMARY KEY (id)
);
EOSQL
from datetime import datetime
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String, DateTime
from setting import Base
from setting import ENGINE
class User(Base):
"""
UserModel
"""
__tablename__ = 'users'
id = Column(Integer, primary_key=True, autoincrement=True)
name = Column(String(200))
created_at = Column(DateTime, default=datetime.now, nullable=False)
updated_at = Column(DateTime, default=datetime.now, nullable=False)
def __init__(self, name):
self.name = name
if __name__ == "__main__":
Base.metadata.create_all(bind=ENGINE)
ポイント
- DBのDockerコンテナを初めて起動した際に、
2_create_table.sh
でUserテーブルを作成する
※ DBが一度作成されている場合は、/Users/${USER}/Volumes/flask_tutorial/postgres
を削除する - flask側にDB上に、どんなテーブルがあるのかをsqlarchemyを使用して定義してあげる
DB 確認
- コンテナを起動
$ docker-compose up -d
Creating network "flask-tutorial_default" with the default driver
Creating flask_tutorial_postgresql ... done
Creating flask_tutorial_pgadmin4 ... done
- pgadminでUserテーブルが作成されていることを確認
DB操作準備
from flask import Flask, request, render_template
from UserModel import User
from setting import session
from sqlalchemy import *
from sqlalchemy.orm import *
# appという名前でFlaskのインスタンスを作成
app = Flask(__name__)
# 登録処理
@app.route('/', methods=["POST"])
def register_record():
name = request.form['name']
session.add(User(name))
session.commit()
return render_template("hello.html", name=name, message="登録完了しました!")
# 取得処理
@app.route('/', methods=["GET"])
def fetch_record():
name = request.args.get('name')
db_user = session.query(User.name).\
filter(User.name == name).\
all()
if len(db_user) == 0:
message = "登録されていません。"
else:
message = "登録されています。"
return render_template("hello.html", name=name, message=message)
if __name__ == '__main__':
app.run()
ポイント
-
操作に必要なものをインポート
- 操作対象のテーブル
- DBの操作を行うのでsessionが必要
from UserModel import User
from setting import session
from sqlalchemy import *
from sqlalchemy.orm import *
- 登録処理
# 登録処理
@app.route('/', methods=["POST"])
def register_record():
name = request.form['name']
session.add(User(name))
session.commit()
return render_template("hello.html", name=name, message="登録完了しました!")
実際に登録している箇所は以下
session.add(User(name))
session.commit()
session.add
でINSERT文を実行
session.commit()
コミットしてる
- 取得処理
# 取得処理
@app.route('/', methods=["GET"])
def fetch_record():
name = request.args.get('name')
db_user = session.query(User.name).\
filter(User.name == name).\
all()
if len(db_user) == 0:
message = "登録されていません。"
else:
message = "登録されています。"
return render_template("hello.html", name=name, message=message)
取得処理は、以下
db_user = session.query(User.name).\
filter(User.name == name).\
all()
session.query(User.name)
で取得したいテーブル.列名
filter(User.name == name)
はWHERE句
all()
でクエリを実行
※ 今回は単純なSELECT文のみ、テーブル結合などもできるので必要に応じて適宜調べてください。
DB操作確認
- コンテナを起動
$ docker-compose up -d
Creating network "flask-tutorial_default" with the default driver
Creating flask_tutorial_postgresql ... done
Creating flask_tutorial_pgadmin4 ... done
- flaskを起動
$ python src/main.py
* Serving Flask app "main" (lazy loading)
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: off
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
- form.htmlで確認
次回
- nginxのdockerコンテナを用意して、静的なページをflaskから切り離す