著者は、無料かつオープンソース基金を、寄付のために書くプログラムの一環として選択しました。
はじめに
ウェブアプリケーションでは、通常、データベースが必要です。データベースはデータの整理されたコレクションであり、持続的なデータを効率的に取得および操作するために使用します。たとえば、ソーシャルメディアアプリケーションでは、ユーザーデータ(個人情報、投稿、コメント、フォロワーなど)が効率的に操作できるようにデータベースに保存されます。データベースにデータを追加したり、取得したり、変更したり、削除したりすることができます。これは、異なる要件や条件に応じて行われます。たとえば、Webアプリケーションでは、ユーザーが新しい投稿を追加したり、投稿を削除したり、アカウントを削除したりするかもしれません。これらのデータを操作するために行うアクションは、アプリケーションの特定の機能に依存します。たとえば、タイトルなしで投稿を追加することを許可したくない場合があります。
Flaskは、Python言語でウェブアプリケーションを作成するための便利なツールと機能を提供する軽量なPythonウェブフレームワークです。 PostgreSQL、またはPostgresは、SQLクエリ言語の実装を提供する関係データベース管理システムです。標準に準拠しており、信頼性の高いトランザクションや読み取りロックなしの同時実行などの高度な機能があります。
このチュートリアルでは、psycopg2
ライブラリを使用して、PythonでPostgreSQLデータベースとやり取りするためのPostgreSQLデータベースアダプタを示す小さな書評ウェブアプリケーションを構築します。Flaskと組み合わせて、データベースサーバへの接続、テーブルの作成、テーブルへのデータ挿入、テーブルからのデータ取得などの基本的なタスクを実行します。
前提条件
-
ローカルのPython 3プログラミング環境。Python 3のローカルプログラミング環境のインストールと設定のチュートリアルに従ってください。このチュートリアルでは、プロジェクトディレクトリを
flask_app
と呼びます。 -
ルート、ビュー関数、およびテンプレートなどの基本的なFlaskの概念の理解。 Flaskに馴染みがない場合は、FlaskとPythonを使用して最初のWebアプリケーションを作成する方法およびFlaskアプリケーションでテンプレートを使用する方法を確認してください。
-
基本的なHTMLの概念の理解。 バックグラウンド知識については、当社のHTMLを使用したウェブサイトの構築方法チュートリアルシリーズを参照してください。
-
ローカルマシンにPostgreSQLがインストールされ、PostgreSQLプロンプトへのアクセスがあります。 Ubuntu 20.04にPostgreSQLをインストールして使用する方法 に従って、PostgreSQLデータベースを設定してください。
ステップ1 — PostgreSQLデータベースとユーザーの作成
このステップでは、Flaskアプリケーション用にflask_db
という名前のデータベースとsammy
という名前のデータベースユーザーを作成します。
Postgresのインストール中に、postgres
という名前の操作システムユーザーが作成され、postgres
PostgreSQL管理ユーザーに対応します。 このユーザーを使用して管理タスクを実行する必要があります。 sudo
を使用し、-iu
オプションでユーザー名を渡します。
次のコマンドを使用して、インタラクティブなPostgresセッションにログインします:
PostgreSQLプロンプトが表示され、要件を設定できます。
まず、プロジェクト用のデータベースを作成します:
注意: すべてのPostgresステートメントはセミコロンで終わらなければなりませんので、問題が発生している場合は、コマンドがそれで終わるようにしてください。
次に、プロジェクト用のデータベースユーザーを作成します。安全なパスワードを選択してください:
その後、この新しいユーザーに新しいデータベースを管理する権限を付与します:
データベースが作成されたことを確認するには、次のコマンドを入力してデータベースのリストを取得します:
リストの中にflask_db
が表示されます。
作業が完了したら、次のコマンドを入力してPostgreSQLプロンプトから終了します:
Postgresは、Pythonを使用してpsycopg2
ライブラリを使ってデータベース情報に接続して管理できるように設定されています。次に、このライブラリをFlaskパッケージと一緒にインストールします。
ステップ2 — Flaskとpsycopg2のインストール
このステップでは、Pythonを使用してデータベースとやり取りするためにFlaskとpsycopg2
ライブラリをインストールします。
仮想環境をアクティブにした状態で、pip
を使用してFlaskとpsycopg2
ライブラリをインストールします:
インストールが正常に完了すると、出力の最後に次のような行が表示されます:
Output
Successfully installed Flask-2.0.2 Jinja2-3.0.3 MarkupSafe-2.0.1 Werkzeug-2.0.2 click-8.0.3 itsdangerous-2.0.1 psycopg2-binary-2.9.2
これで、必要なパッケージが仮想環境にインストールされました。次に、データベースに接続して設定します。
ステップ3 — データベースの設定
このステップでは、flask_db
データベースに接続し、本を格納するためのテーブルを作成し、いくつかの書籍とレビューを挿入するための Python ファイルを flask_app
プロジェクトディレクトリに作成します。
まず、プログラミング環境がアクティブ化されていることを確認し、flask_app
ディレクトリに init_db.py
という新しいファイルを開きます。
このファイルでは、flask_db
データベースに接続し、books
というテーブルを作成し、サンプルデータを使用してテーブルを満たします。以下のコードを追加します:
ファイルを保存して閉じます。
このファイルでは、まず、データベースのユーザー名とパスワードを保存するための環境変数にアクセスするために使用する os
モジュールをインポートします。これにより、ソースコードでそれらが見えなくなります。
psycopg2
ライブラリをインポートします。その後、psycopg2.connect()
関数を使用して flask_db
データベースに接続します。この場合、ホストを指定し、localhost とします。データベース名は database
パラメーターに渡します。
プログラミング環境で設定した環境変数にアクセスできる os.environ
オブジェクトを介して、ユーザー名とパスワードを提供します。データベースのユーザー名は DB_USERNAME
という環境変数に保存し、パスワードは DB_PASSWORD
という環境変数に保存します。これにより、ユーザー名とパスワードをソースコードの外部に保存し、ソースコードがソースコントロールに保存されたり、インターネット上のサーバーにアップロードされたりした場合でも、機密情報が漏洩することはありません。攻撃者がソースコードにアクセスしても、データベースにアクセスすることはできません。
connection.cursor()
メソッドを使用して、cur
というカーソルを作成します。これにより、Python コードがデータベースセッションで PostgreSQL コマンドを実行できるようになります。
カーソルの execute()
メソッドを使用して、すでに存在する場合は books
テーブルを削除します。これにより、books
という別のテーブルが存在する可能性がある場合に混乱することがなくなります(たとえば、異なる列がある場合など)。ここではまだテーブルを作成していないので、SQL コマンドは実行されません。この init_db.py
ファイルを実行するたびに既存のデータがすべて削除されますので、注意してください。私たちの目的では、データベースを初期化するためにこのファイルを一度だけ実行しますが、挿入したデータを削除して初期のサンプルデータから再開するために再度実行したいかもしれません。
その後、CREATE TABLE books
を使用して、次の列を持つ books
という名前のテーブルを作成します:
id
:serial
型の ID。これは自動的に増加する整数です。この列は、PRIMARY KEY
キーワードを使用して指定される 主キー を表します。データベースは、各エントリに対してこのキーに一意の値を割り当てます。title
:varchar
型の書籍のタイトル。これは制限付きの可変長文字タイプです。varchar (150)
は、タイトルが最大で 150 文字であることを意味します。NOT NULL
は、この列が空であってはならないことを示します。author
:書籍の著者。最大 50 文字までです。NOT NULL
は、この列が空であってはならないことを示します。pages_num
:書籍のページ数を表す整数です。NOT NULL
は、この列が空であってはならないことを示します。review
:書評。text
タイプは、レビューが任意の長さのテキストであることを示します。date_added
:書籍がテーブルに追加された日付。DEFAULT
は、列のデフォルト値をCURRENT_TIMESTAMP
に設定し、これは書籍がデータベースに追加された時間です。id
と同様に、この列の値を指定する必要はありません。自動的に入力されます。
テーブルを作成した後、カーソルの execute()
メソッドを使用して、2つの書籍をテーブルに挿入します。A Tale of Two Cities(チャールズ・ディケンズ著)と、Anna Karenina(レオ・トルストイ著)です。値を SQL ステートメントに渡すために %s
プレースホルダーを使用します。psycopg2
は、背後で挿入を処理し、SQL インジェクション攻撃 を防ぎます。
テーブルに書籍データを挿入したら、トランザクションをコミットしてデータベースに変更を適用するために、connection.commit()
メソッドを使用します。その後、カーソルを cur.close()
で閉じ、接続を conn.close()
で閉じてクリーンアップします。
データベース接続を確立するには、次のコマンドを実行して DB_USERNAME
と DB_PASSWORD
環境変数を設定します。自分のユーザー名とパスワードを使用してください。
次に、ターミナルで python
コマンドを使用して init_db.py
ファイルを実行します。
ファイルの実行がエラーなしで完了すると、新しい books
テーブルが flask_db
データベースに追加されます。
新しい books
テーブルを確認するために、対話型のPostgresセッションにログインします。
\c
コマンドを使用して flask_db
データベースに接続します。
その後、books
テーブルから書籍のタイトルと著者を取得するために SELECT
文を使用します。
以下のような出力が表示されます。
title | author
----------------------+------------------
A Tale of Two Cities | Charles Dickens
Anna Karenina | Leo Tolstoy
\q
を使用して対話型セッションを終了します。
次に、小さなFlaskアプリケーションを作成し、データベースに接続して挿入した2つの書籍レビューを取得し、インデックスページに表示します。
ステップ4 — 書籍の表示
このステップでは、データベース内の書籍を取得し、それらを表示するFlaskアプリケーションを作成します。
プログラムの環境がアクティブ化され、Flaskがインストールされている場合、flask_app
ディレクトリ内の app.py
ファイルを編集します。
このファイルはデータベース接続を設定し、その接続を使用する単一のFlaskルートを作成します。次のコードをファイルに追加します。
ファイルを保存して閉じます。
ここでは、os
モジュール、psycopg2
ライブラリ、およびflask
パッケージからFlask
クラスとrender_template()
をインポートします。その後、app
というFlaskアプリケーションインスタンスを作成します。
get_db_connection()
という関数を定義し、DB_USERNAME
とDB_PASSWORD
環境変数に保存されているユーザー名とパスワードを使用してflask_db
データベースに接続します。この関数は、データベースへのアクセスに使用するconn
接続オブジェクトを返します。
次に、app.route()
デコレータを使用してメインの/
ルートとindex()
ビュー関数を作成します。 index()
ビュー関数では、get_db_connection()
関数を使用してデータベース接続を開き、カーソルを作成し、SELECT * FROM books;
SQLステートメントを実行してデータベース内のすべての書籍を取得します。取得したデータをbooks
変数に保存するためにfetchall()
メソッドを使用します。最後に、カーソルと接続を閉じます。最後に、books
変数でデータベースから取得した書籍のリストを渡してindex.html
というテンプレートファイルをレンダリングするためにrender_template()
関数を呼び出します。
データベースにある本をインデックスページに表示するには、まずすべての基本的なHTMLコードを持つベーステンプレートを作成し、他のテンプレートがコードの繰り返しを避けるために使用します。次に、index()
関数でレンダリングした index.html
テンプレートファイルを作成します。テンプレートについて詳しくは、Flaskアプリケーションでテンプレートを使用する方法 を参照してください。
templates
ディレクトリを作成し、次に base.html
という新しいテンプレートを開きます:
base.html
ファイル内に次のコードを追加します:
ファイルを保存して閉じます。
このベーステンプレートには、他のテンプレートで再利用するために必要なすべてのHTMLのボイラープレートが含まれています。title
ブロックは各ページのタイトルを設定するために置換され、content
ブロックは各ページの内容で置換されます。ナビゲーションバーには、インデックスページ用のリンクとして、url_for()
ヘルパー関数を使用して index()
ビュー関数にリンクするものと、アプリケーションに含めることを選択した場合の About ページ用のリンクが含まれています。
次に、index.html
というテンプレートを開きます。これは app.py
ファイルで参照されるテンプレートです:
次のコードを追加します:
ファイルを保存して閉じます。
このファイルでは、ベーステンプレートを拡張し、content
ブロックの内容を置換します。<h1>
見出しを使用してタイトルも表示します。
行の中でJinja for
ループを使用して、books
リスト内の各書籍を処理します。書籍のID(最初のアイテム)をbook[0]
を使用して表示します。その後、書籍のタイトル、著者、ページ数、レビュー、および書籍が追加された日付を表示します。
仮想環境がアクティブ化された状態でflask_app
ディレクトリにいる場合、FLASK_APP
環境変数を使用してアプリケーション(この場合はapp.py
)についてFlaskに通知します。次に、アプリケーションを開発モードで実行し、デバッガにアクセスします。Flaskデバッガの詳細については、Flaskアプリケーションでエラーを処理する方法を参照してください。次のコマンドを使用してこれを行います:
既に設定していない場合は、DB_USERNAME
およびDB_PASSWORD
環境変数を設定してください:
次に、アプリケーションを実行します:
開発サーバーが実行されている状態で、ブラウザを使用して次のURLにアクセスします:
http://127.0.0.1:5000/
最初の起動時にデータベースに追加した書籍が表示されます。
データベース内の書籍をインデックスページに表示しました。次に、ユーザーが新しい書籍を追加できるようにします。次のステップで書籍を追加するための新しいルートを追加します。
ステップ5 — 新しい本の追加
このステップでは、新しい本やレビューをデータベースに追加するための新しいルートを作成します。
ユーザーが書籍のタイトル、著者、ページ数、および書籍のレビューを入力するウェブフォーム付きのページを追加します。
開発サーバーを実行したまま、新しいターミナルウィンドウを開いてください。
まず、app.py
ファイルを開きます:
ウェブフォームを処理するために、flask
パッケージからいくつかのものをインポートする必要があります:
- 提出されたデータにアクセスするためのグローバルな
request
オブジェクト。 - URLを生成するための
url_for()
関数。 - 書籍をデータベースに追加した後、ユーザーをインデックスページにリダイレクトするための
redirect()
関数。
これらのインポートをファイルの最初の行に追加します:
次に、app.py
ファイルの最後に次のルートを追加します:
ファイルを保存して閉じます。
このルートでは、methods
パラメータにタプル('GET', 'POST')
を渡して、GETリクエストとPOSTリクエストの両方を許可します。GETリクエストはサーバーからデータを取得するために使用されます。POSTリクエストは特定のルートにデータを投稿するために使用されます。デフォルトでは、GETリクエストのみが許可されています。ユーザーが最初に/create
ルートにGETリクエストを使用してリクエストすると、create.html
という名前のテンプレートファイルがレンダリングされます。後で、新しい書籍を追加するためのウェブフォームにデータを入力して送信する場合のPOSTリクエストを処理するために、このルートを編集します。
新しいcreate.html
テンプレートを開きます:
以下のコードを追加します:
ファイルを保存して閉じます。
ベーステンプレートを拡張し、見出しをタイトルとして設定し、<form>
タグを使用してフォームがPOSTリクエストを送信することを示す属性method
をpost
に設定します。
title
という名前のテキストフィールドがあり、これを使用して/create
ルートでタイトルデータにアクセスします。
著者のためのテキストフィールド、ページ数のための数値フィールド、書籍レビューのためのテキストエリアがあります。
最後に、フォームの末尾に送信ボタンがあります。
開発サーバーが実行されている状態で、ブラウザを使用して/create
ルートに移動します:
http://127.0.0.1:5000/create
新しい書籍を追加するための入力フィールド、その著者のためのフィールド、および書籍のページ数のためのフィールド、書籍のレビューのためのテキストエリア、および送信ボタンがあるページが表示されます。
フォームに記入して送信すると、サーバーにPOSTリクエストが送信されますが、/create
ルートでPOSTリクエストを処理していないため、何も起こりません。
app.py
を開いて、ユーザーが送信したPOSTリクエストを処理するようにします:
/create
ルートを以下のように編集します:
ファイルを保存して閉じます。
POSTリクエストを次のように処理します:if request.method == 'POST'
条件の中で。タイトル、著者、ページ数、およびユーザーが送信したレビューをrequest.form
オブジェクトから取得します。
get_db_connection()
関数を使用してデータベースを開き、カーソルを作成します。そして、books
テーブルにユーザーが送信したタイトル、著者、ページ数、およびレビューを挿入するINSERT INTO
SQLステートメントを実行します。
トランザクションをコミットし、カーソルと接続を閉じます。
最後に、ユーザーをインデックスページにリダイレクトし、既存の書籍の下に新しく追加された書籍を表示します。
開発サーバーが実行されている状態で、ブラウザを使用して/create
ルートに移動します:
http://127.0.0.1:5000/create
フォームにデータを入力して送信します。
インデックスページにリダイレクトされ、新しい書籍レビューが表示されます。
次に、ナビゲーションバーに作成ページへのリンクを追加します。base.html
を開きます:
ファイルを以下のように編集します:
ファイルを保存して閉じます。
ここでは、ナビゲーションバーに、作成ページを指す新しいリンクを追加します。
インデックスページを更新すると、ナビゲーションバーに新しいリンクが表示されます。
これで、新しい本のレビューを追加するためのWebフォームがあるページができました。Webフォームの詳細については、FlaskアプリケーションでWebフォームを使用する方法を参照してください。より高度で安全なWebフォームの管理方法については、Flask-WTFを使用してWebフォームを使用および検証する方法を参照してください。
結論
PostgreSQLデータベースと通信する小さな書評Webアプリケーションを構築しました。Flaskアプリケーションには、データベースへの新しいデータの追加、データの取得、およびページへの表示など、基本的なデータベース機能があります。
Flaskについてもっと読みたい場合は、Flaskシリーズの他のチュートリアルをチェックしてください。