akatak blog

プログラム初心者の50代ビジネスマンがセカンドキャリアを目指して働きながらPythonを中心に独学していましたが、昨年IT系企業に転職。新規事業開発の仕事をすることになりました。自らの覚え書きや成果物、感じたことなどを脈絡もなく書き連ねるブログです。

FlaskとSQLAlchemyで読書記録Webアプリを作る(1)

先日、日経ソフトウェア(2019年3月号)を見ていたら『Flask+SQLite3でWeb-DBアプリ開発!蔵書管理データベースで基本をマスターしよう』という記事が掲載されていました。それはそれで作ってみたのですが、sqlite3に依存するコードとなっていたので、将来的にHeroku等のクラウドサービスへデプロイし、PostgresSQLの利用を考える場合には、コードを書き換えなくてはいけなくなります。

そこで、上記の記事を参考にしつつ、データーベースの種類が変わってもコードの変更が最小限になるように、SQLAlchemy等を利用した簡単な読書記録Webアプリを新たに作りましたので、次回以降ご紹介したいと思います。今回は、そのWebアプリで利用したパッケージを先にご紹介します。

Flaskとは

Flaskは、PythonによるWebアプリケーション開発用のフレームワークです。開発者がマイクロフレームワークと呼んでいるように軽量で最小限の機能しかない一方で、柔軟性が高いという特徴を持っています。Pythonにおける有名なフレームワークであるDjangoはWebアプリケーションの作成までの決まりごとが多く、ハードルが高いため、取り敢えずでいいからWebアプリケーションを簡単に作ってみたいという方には Flaskがオススメです。

Flask公式ホームページ

SQLAlchemyとは

SQLAlchemyはPythonのORM(OBject Relational Mapper)です。Python用ORMの中では人気があり、広く利用されているようです。

ORM(Object-relational mapping、オブジェクト関係マッピング)とは、データベースとオブジェクト指向プログラミングの間の非互換なデータを変換するプログラミング技法のことをいいます(出典:Wikipedia)。Object-relational Mapperは、そうしたプログラム技法を利用したパッケージのことを指しています。

これにより、SQLiteMySQLPostgreSQLといったデータベースの各々異なるSQLを直接記述することなく、Pythonオブジェクトを通じて、データベースを扱えることができます。加えて、データベースの種類に関係なく、共通のコードを利用してデータベースを取り扱うことができるので、コードを変更せずに、自分のパソコンではSQLiteを利用して、Herokuにデプロイした後はPostgrteSQLを利用するといったことが可能となります。

SQLAlchemy ORM Tutorial

Flask-SQLAlchemyとは

Flask-SQLAlchemyは、FlaskにおいてSQLAlchemyをより簡単に利用するための拡張パッケージです。これにより、Flaskからより簡単にSQLAlchemyを利用できるようになります。

例えば、Flask-SQLAlchemyでは、dbオブジェクトを通じて、テーブルの作成や検索を実行できるようになります。SQLAlchemyのみの場合とFlask-SQLAlchemyを利用した場合の違いは、例えば以下の通り。

【導入(前置き)部分】
▪️SQLAlchemyのみの場合

from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String

engine = create_engine('sqlite:////tmp/test.db')
Base = declarative_base()

class User(Base):
    id = Column(Integer, primary_key=True)
    Username = Column(String)
    email = Column(String)
    def __repr__(self):
        return '<User %r>' % self.username

▪️Flask-SQLAlchemyを利用した場合

from flask import Flask
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////tmp/test.db'
db = SQLAlchemy(app)

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    Username = db.Column(db.String)
    email = db.Column(db.String)
    def __repr__(self):
        return '<User %r>' % self.username

【テーブルの作成】
▪️SQLAlchemyのみの場合

Base.metadata.create_all(engine)

▪️Flask-SQLAlchemyを利用した場合

db.create_all()

【データの追加・コミット(その準備)】
▪️SQLAlchemyのみの場合

from sqlalchemy.orm import sessionmaker
from yourapplication import User

Session = sessionmaker(bind=engine)
session = Session()

user1 = User(username='user1', email='user1@example.com')

session.add(user1)
session.commit()

▪️Flask-SQLAlchemyを利用した場合

from yourapplication import db, User

user1 = User(username='user1', email='user1@example.com')

db.session.add(user1)
db.session.commit()

【テーブルを検索】
▪️SQLAlchemyのみの場合

session.query(User).order_by(User.id)

▪️Flask-SQLAlchemyを利用した場合

db.session.query(User).order_by(User.id)

これ以上は省略しますが、flask-sqlalchemyを利用した方が、dbオブジェクトを通じて、テーブルを作成したり、検索したりできますので、便利かと思います。

flask-sqlalchemy Documentation

Flask-Migrateとは

Flask-Migrateは、Flaskアプリケション用のデータベース移行ツールで、Alembicというパッケージを利用しています。このFlask-Migrateにより、コマンドラインによるデータベース操作が可能となります。

例えば、'flask db init'とコマンドラインに入力すると、models.py等のPythonモジュールに記載された各クラスからデータベースのテーブルを作成してくれますので、Pythonスクリプトを立ち上げて、db.create_all()等をいちいち実行しなくて済みます。また、データベースの構造を変えていく際に、履歴を保存するほか、データの移行を実行したり、戻したりすることが可能となります。

flask-Migrate Documentation

なお、AlembicはSQLAlchemyの作者が作成したデータベース移行ツールで、以下の機能を提供しています(alembic 1.0.10)。
- テーブルその他の構造を変更するためにデータベースに対してALTERステートメントを発行
- 移行のためのスクリプトを記述する仕組みを提供。各スクリプトは、対象となるデータベースを新しいバージョンにアップグレードできる特定の一連の手順と、オプションで、同じ手順を逆の順序でダウングレードできる一連の手順を示す
- スクリプトを順次実行することを許可

flask-WTFとは

flask-WTFはWTFormsというパッケージをFlaskで利用可能とするパッケージです。WTFormsは、flaskその他のWebフレームワークで利用可能なパッケージの一つで、Pythonを利用して各種フォームの作成や入力時のチェックを柔軟に行うことができます。

flask-WTF Documentation

今回は以上です。次回以降、具体的にコーディング事例をご紹介します。

akatak.hatenadiary.jp

akatak.hatenadiary.jp

akatak.hatenadiary.jp

akatak.hatenadiary.jp

akatak.hatenadiary.jp

akatak.hatenadiary.jp