1
1

More than 1 year has passed since last update.

Flask と PostgreSQL Serverの接続覚書

Posted at

環境作成

# 仮想環境の作成 + activate
$ python -m venv flask_to_postgresql
$ cd flask_to_postgresql/Scripts
$ ./activate

# 必要なパッケージ取得
$ python -m pip install --upgrade pip
$ pip install flask psycopg2-binary

# 環境確認
$ python --version
Python 3.9.13
$ pip list
Package            Version
------------------ -------
click              8.1.3
colorama           0.4.6
Flask              2.2.2
importlib-metadata 5.1.0
itsdangerous       2.1.2
Jinja2             3.1.2
MarkupSafe         2.1.1
pip                22.3.1
psycopg2-binary    2.9.5
setuptools         58.1.0
Werkzeug           2.2.2
zipp               3.11.0

psycopg2-binaryはPostgreSQL Server接続用のパッケージ

参考サイト

軌跡

flask_to_postgresql.py
from flask import Flask, render_template
import psycopg2
import psycopg2.extras

# Flask作成
app = Flask(__name__)

# ~/ にアクセスした際に表示するもの
@app.route('/')
def index():
    """_summary_
    従業員リストを表示
    """
    # PostgreSQL Serverとの接続を定義
    conn = psycopg2.connect(
        host='localhost',
        port=5432,
        database='test',
        user='testuser',
        password='testpassword',
    )

    # PostgreSQL Serverと接続を作成
    cur = conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
    # SQLを投入して情報取得
    cur.execute('select * from employee order by employee_id')
    # 結果を取得
    employee_list = cur.fetchall()
    # 接続終了
    conn.close()

    # データをhtmlに渡して表示
    return render_template(
        'flask_to_postgresql.html',
        title='Flask PostgreSQL',
        dataset=employee_list
    )

if __name__ == '__main__':
    # デバッグ出力を有効化
    app.debug = True
    # appを実行(ループバックアドレス + 80番ポート)
    app.run(host='127.0.0.1', port=80)
templates/flask_to_postgresql.html
<!DOCTYPE html>
<html lang="ja">
    <head>
        <meta charset="UTF-8">
        <title>{{ title }}</title>
    </head>
    <body>
        <h2>社員一覧</h2>
        <ul>
            {% for line in dataset %}
            <li>{{ line.employee_id }} : {{ line.name }} : {{ line.abbreviation }}</li>
            {% endfor %}
        </ul>
    </body>
</html>

用語メモ

理解メモ

  • psycopg2の使い方の順序は以下
    1. DBの接続情報を作る(conn = psycopg2.connect(~)
    2. DBに接続する
    3. SQLを投入する
    4. 結果を取得する
    5. コネクションを閉じる
    6. 取得した結果を処理する
  • psycopg2.extras.DictCursorとは
  • テンプレートに渡す際のdataset=employee_list
    • datasetは定型句ではなく何でも良い
    • .html側は上記で指定された変数に対して操作できる

実行結果を辞書形式で取得 とは

dict_what.py
import psycopg2
import psycopg2.extras

def main():
    """_summary_
    社員リストを表示
    """
    # PostgreSQL Serverとの接続を定義
    conn = psycopg2.connect(
        host='localhost',
        port=5432,
        database='srvrec',
        user='srvrec',
        password='vorpoc-2020-srvrec',
    )

    # PostgreSQL Serverと接続を作成
    cur = conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
    # SQLを投入して情報取得
    cur.execute('select * from employee order by employee_id')
    # 結果を取得
    row = cur.fetchall()
    print(row)

    # PostgreSQL Serverと接続を作成
    cur = conn.cursor()
    # SQLを投入して情報取得
    cur.execute('select * from employee order by employee_id')
    # 結果を取得
    bow = cur.fetchall()
    print(bow)
    # 接続終了
    conn.close()

if __name__ == '__main__':
    main()

dict指定のrowと、無指定のbowの出力差を見てみる

$ python ./dict_what.py
[['100001', '北条 泰時'], ['100002', '北条 政子'], ['100003', '北条 時房'], ['100004', '三浦 義村']]
[('100001', '北条 泰時'), ('100002', '北条 政子'), ('100003', '北条 時房'), ('100004', '三浦 義村')]

あれ、てっきり{}で表示されるかと思ったけど違うのかな

dict_what.py
import psycopg2
import psycopg2.extras

def main():
    """_summary_
    社員リストを表示
    """
    # PostgreSQL Serverとの接続を定義
    conn = psycopg2.connect(
        host='localhost',
        port=5432,
        database='srvrec',
        user='srvrec',
        password='vorpoc-2020-srvrec',
    )

    # PostgreSQL Serverと接続を作成
    cur = conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
    # SQLを投入して情報取得
    cur.execute('select * from employee order by employee_id')
    # 結果を取得
    row = cur.fetchone()
    print(row)
    print(type(row))

    # PostgreSQL Serverと接続を作成
    cur = conn.cursor()
    # SQLを投入して情報取得
    cur.execute('select * from employee order by employee_id')
    # 結果を取得
    bow = cur.fetchone()
    print(bow)
    print(type(bow))
    # 接続終了
    conn.close()

if __name__ == '__main__':
    main()
$ python .\dict_what.py
['100001', '北条 泰時']
<class 'psycopg2.extras.DictRow'>
('100001', '北条 泰時')
<class 'tuple'>

一応辞書型になってた。こっちのほうが使いやすそう

1
1
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
1
1