Linuxを日常的に使う実験ブログ

python製フレームワークBottleで簡単なWebアプリを作る(その2)

 2018-07-07

 プログラミング

こんにちは。今回のテーマは『【python】Bottleフレームワークで簡単なWebアプリを作る(その2)』です。BottleというシンプルなWebフレームワークを使って簡単なwebアプリを作ってみる企画の2回めです。今回はBottleとは少し離れてしまいますが、SQLAlchemyをつかったデータベースとアプリの連携について書いていきたいと思います。 ※本記事はpython製フレームワークBottleで簡単なWebアプリを作る(その1)の続きとして書かれていますので、初めての方はまずコチラをご覧になることをオススメします。 (2018-12-15)加筆修正しました。また、ソース全体が見渡せるようにGitHubにソースコードをUPしました。 [adsense02] 【目次】 DBへの登録機能を付与する DBの準備 SQLAlchemyって何? SQLAlchemyの導入 モデルの作成 テーブルの作成 登録処理 次回予告

DBへの登録機能を付与する

前回は登録フォームと確認画面への遷移部分を作成し、Bottleのルーティング機能を中心に見てきました。今回はBottleからは少し離れてデータベース周りの処理を行っていきます。なのでBottle特有の処理はあまり登場しません。

DBの準備

まずはデータベースの準備をしましょう。今回はMariaDB(MySQL)を使用します。今回は主題ではないのでmysql自体の操作については簡単に触れるのみにします。

データベースの作成

まずはmysqlにroot権限でログインします。

mysql -u root -p

パスワード入力してログイン

データベースを作成します。今回はbook_dataという名前で作成します。

[mysql] > cleate database book_data;

ユーザーの作成

book_dataにアクセスするためのユーザーをパスワード付きで作成します。

[mysql] > create user bookuser identified by ‘{PASSWORD}‘;

作成したbookuserにbook_dataへの権限を付与します。

[mysql] > grant all on book_data.* to bookuser@localhost identified ‘{PASSWORD}‘;

SQLAlchemyって何?

SQLAlchemyはphthon製のORM(Object-relational mapping)です。語弊を恐れずに簡単に言うならばオブジェクトと関連データベースを繋いでくれる役割を果たしてくれるものです。プログラマはORMを利用することでSQLクエリを書くことなく、直感的なオブジェクト操作でCURD操作をすることが出来ます。(まあ、複雑な処理になるとSQLクエリ直接実行することもあるのですが)

SQLAlchemyの導入

SQLAlchemyの導入ですが、今回はpipを使ってインストールします。

pip install sqlalchemy

また、python3でmysqlを使うためにmysqlclientも入れておきます。

pip install mysqlclient

モデルの作成

準備ができましたのでSQLAlchemyを用いてモデルを作成していきます。今回は以下のモデルを作成します。

  • ID: id(int)
  • 書籍名: name(varchar)
  • 巻数: volume(varchar)
  • 著者: author(varchar)
  • 出版社 : publisher(varchar)
  • メモ・感想: memo(text)
  • 作成日時: create_date(datetime)
  • 削除フラグ: del(tinyint)

models.pyを以下のように生成します。(全体のディレクトリ構成はpython製フレームワークBottleで簡単なWebアプリを作る(その1)を参考にしてください) [python] from sqlalchemy import Column, Integer, String, Text, text, create_engine, DATETIME from sqlalchemy.orm import sessionmaker from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.dialects.mysql import TINYINT from datetime import datetime URL = ‘mysql://bookuser:{##パスワード##}@localhost/pass_data?charset=utf8’ engin = create_engine(URL, echo=True) Base = declarative_base() Session = sessionmaker(bind=engin) session = Session() class Books(Base): __tablename__ = “books” id_ = Column(‘id’, Integer, primary_key = True) name = Column(‘name’, String(255)) volume = Column(‘volume’, String(255)) author = Column(‘author’, String(255)) publisher = Column(‘publisher’, String(255)) memo = Column(‘memo’, Text()) create_date = Column(‘create_date’, DATETIME, server_default=text(‘NOW()’), nullable=False) delFlg = Column(‘del’, TINYINT(4), server_default=text(‘0’), nullable=False) if __name__ == “__main__”: Base.metadata.create_all(engin) [/python] {##パスワード##}の部分にはbookuser用に作成したパスワードを設定して下さい。SQLAlchemyではデータベースに接続するURLを設定しenginを作成します。データベース毎の違いはここまでで、これ以降は共通の処理で対応出来ます。 declarative_base関数で作成したBaseモデルを継承して各モデルを作成します。また、SQLAlchemyではデータベースで処理を行う際にsessionというオブジェクトで処理を行いますのでsessionも作成しておきます。 ※コメントにて指摘頂いた箇所につきソースコード修正しました。(2018/11/12)

テーブルの作成

では、モデルが作成できたので、このモデルを基にデータベースにテーブルを作りましょう。models.pyで [python] if __name__ == “__main__”: Base.metadata.create_all(engin) [/python] の箇所はこのために記載しました。models.pyを実行することでモデルをベースにテーブルが作られます。

$ cd [プロジェクトディレクトリ] $ python3 models.py

これでテーブルが作成されました。試しにmysqlで確かめてみましょう。

$ mysql -u bookuser -p[パスワード] book_data

mysql内で以下のコマンドを実行します。

[mysql] > show tables;

登録処理

モデルの準備とデータベースへのテーブル作成ができましたので、フォームから投稿されたデータをデータベースに登録する処理を書いていきます。

routes.pyの修正

routes.pyにregist関数を追加します。 [python] @app.route(‘/regist’, method=‘POST’) def regist(): # データ受取 name = request.forms.decode().get(‘name’); volume = request.forms.decode().get(‘volume’); author = request.forms.decode().get(‘author’); publisher = request.forms.decode().get(‘publisher’); memo = request.forms.decode().get(‘memo’); registId = request.forms.decode().get(‘id’) if request.forms.get(‘next’) == ‘back’: response.status = 307 response.set_header(“Location”, ‘/add’) return response else: if registId is not None: # 更新処理 books = session.query(Books).filter(Books.id_==registId).first() books.name = name books.volume = volume books.author = author books.publisher = publisher books.memo = memo session.commit() session.close() else: # データの保存処理 books = Books( name = name, volume = volume, author = author, publisher = publisher, memo = memo) session.add(books) session.commit() session.close() [/python] これでlocalhost:8080/registにデータをPOSTするとデータベースに登録されるようになります。確認画面で「戻る」ボタンが押された場合にはPOSTされる’next’の値が’back’になるためhiddenのinputフォームに登録されている各値をlocalhost:8080/add(登録画面)にPOSTして画面遷移する作りとしました。今回追加した機能はPOSTされたデータをデータベースに追加する処理ですが、将来的には一覧画面からデータの更新処理も行いたいので、registIdの有無で場合分けを行っています。 データの登録処理はモデルを生成してsession.add関数に作成したモデルを入れるだけです。session.commitが行われるまで実行されないので気をつけて下さい。また、処理が終わったらsession.closeすることもお忘れなく。 データの更新処理はsession.query関数にfilterを適用し目的のデータをモデルとして取り出し、そのモデルに修正を加えてcommitすればOKです。この程度の処理でしたらSQLクエリを発行しても苦ではないと思いますが、pythonのモデルとしてデータベース処理が扱える点は便利ですね。

テンプレートファイルの修正

確認画面のテンプレートファイルviews/confirm.htmlにも以下の様に修正を加え、localhost:8080/registに登録データをPOSTするように修正します。 [html]

[/html] ここの部分を以下のように修正します。 [html] [/html]

次回予告

今のままではデータ保存処理を行った後に、確認画面にとどまってしまいますので今後はデータ保存後は一覧画面に遷移するようにします。一覧画面作成を中心にデータの更新、削除等を行っていく予定です。

最後に

今回も駆け足になってしまいました。全体の完成図や動きが分からないと実感が掴めないと思いますので実際に動くデモサイトの準備をしているところです。次回が最終回の予定です。 記事のためにソースを修正しながら書いた部分でモジュールの読込等に不備がありました。全体が見渡せるようにGitHubにソースコードをUPしました。記事を補完する役割として、ご参考にしていただけると幸いです。 【関連記事】 python製フレームワークBottleで簡単なWebアプリを作る(その1) 【python】Bottleフレームワークで簡単なWebアプリを作る(その3) [adsense]