はじめに

Flask + SQLAlchemy + MariaDB で Web サービスを個人開発しようと試みたところ、想像以上に詰まりました。そこで、僕のように辛い時間を過ごすことなく Flask で Web サービスを開発し始められるように手順を記事化しました。好評だったら続編も書くので、もし内容が良かったら Twitter 等でシェアして頂けると幸甚です 😀 笑

Github

完成品はこちら

使用ツール等

Flask とは

Flask は軽量の WSGI Web アプリケーションフレームワークです。複雑なアプリケーションにスケールアップする機能を備えた、迅速かつ簡単に開始できるように設計されています。

Flask is a lightweight WSGI web application framework. It is designed to make getting started quick and easy, with the ability to scale up to complex applications.

『Flask』Armin Ronacher and contributors

SQLAlchemy とは

SQLAlchemy は、Python SQL ツールキットおよびオブジェクトリレーショナルマッパーであり、アプリケーション開発者に SQL のフルパワーと柔軟性を提供します。

SQLAlchemy is the Python SQL toolkit and Object Relational Mapper that gives application developers the full power and flexibility of SQL.

zeekofile『SQLAlchemy』SQLAlchemy authors and contributors

MariaDB とは

MariaDB は、コミュニティが開発し、商用でサポートされている MySQL リレーショナルデータベース管理システムのフォークであり、GNU General Public License の下でフリーでオープンソースのソフトウェアを維持することを目的としています。

MariaDB is a community-developed, commercially supported fork of the MySQL relational database management system, intended to remain free and open-source software under the GNU General Public License.

『MariaDB』Wikipedia

phpMyAdmin とは

phpMyAdmin は、MySQL および MariaDB 用の無料のオープンソース管理ツールです。

phpMyAdmin is a free and open source administration tool for MySQL and MariaDB.

『phpMyAdmin』phpMyAdmin contributors

最低限の Web アプリケーションを構築する

プログラムを書くための準備

まずはプログラムを書ける状態にします。下記を参考にしてディレクトリを構成して下さい。

初期のディレクトリ構成

├── application
│   ├── __init__.py
│   ├── config.py
│   └── database.py
└── run.py

次に、application ディレクトリと run.py ファイルを配置した階層に移動して下さい。そして、下記のコマンドを実行して下さい。

pipenv install コマンド

pipenv install flask flask-sqlalchemy sqlalchemy pymysql flask-migrate

PipfilePipfile.lock が生成されていたら OK です!

Flask と SQLAlchemy を使用するための準備

database.py

from flask_sqlalchemy import SQLAlchemy

db = SQLAlchemy()


def initialize_database(app):
    db.init_app(app)

config.py

import os


class DevelopmentConfig:
    # Flask
    DEBUG = True

    # SQLAlchemy
    SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://{user}:{password}@{host}:{port}/database?charset=utf8mb4'.format(**{
        'user': os.getenv('DB_USER', 'root'),
        'password': os.getenv('DB_PASSWORD', '[email protected]'),
        'host': os.getenv('DB_HOST', 'localhost'),
        'port': os.getenv('DB_PORT', '7582')
    })
    SQLALCHEMY_TRACK_MODIFICATIONS = False
    SQLALCHEMY_ECHO = True


Config = DevelopmentConfig

__init__.py

from flask import Flask

from application.database import initialize_database


def create_app():
    app = Flask(__name__)
    app.config.from_object('application.config.Config')
    initialize_database(app)

    return app


app = create_app()

run.py

from application import create_app

app = create_app()

if __name__ == '__main__':
    app.run()

Docker で MariaDB のコンテナを起動する

Flask と SQLAlchemy を使用する準備が整いました。次はデータベースを作成します。今回は docker-compose.yml を使用して MariaDB コンテナの作成および起動を行います。下記を参考にして docker-compose.yml を作成して下さい。

現在のディレクトリ構成

├── Pipfile
├── Pipfile.lock
├── application
│   ├── __init__.py
│   ├── config.py
│   └── database.py
├── docker-compose.yml
└── run.py

docker-compose.yml

version: '3'
services:
  db:
    container_name: example-db
    image: mariadb:latest
    environment:
      MYSQL_ROOT_PASSWORD: [email protected]
      MYSQL_DATABASE: database
    volumes:
      - ./docker/db/data:/var/lib/mysql
      - ./docker/db/my.cnf:/etc/mysql/conf.d/my.cnf
    ports:
      - 7582:3306
  phpmyadmin:
    container_name: example-admin
    image: phpmyadmin/phpmyadmin
    environment:
      - PMA_ARBITRARY=1
      - PMA_USER=root
      - [email protected]
    ports:
      - 10111:80

docker-compose.yml を配置した階層で下記のコマンドを実行して下さい。ついでに phpMyAdmin コンテナも作成・起動されるようにしてます。

コンテナの構築、作成、起動およびアタッチ(デタッチド・モード)

docker-compose up -d

処理が終了したら下記のコマンドで問題なく動作しているか確認して下さい。

コンテナリストの表示

docker ps

docker ps コマンドを実行すると、下記のようなものが表示されるはずです。

docker ps の結果

CONTAINER ID        IMAGE                   COMMAND                  CREATED             STATUS              PORTS                    NAMES
6b95eb3973c9        phpmyadmin/phpmyadmin   "/docker-entrypoint.…"   6 minutes ago       Up 6 minutes        0.0.0.0:10111->80/tcp    example-admin
3c6901cfa49d        mariadb:latest          "docker-entrypoint.s…"   6 minutes ago       Up 6 minutes        0.0.0.0:7582->3306/tcp   example-db

両方の STATUS が Up になっていれば OK です!

先程、MariaDB のついでに phpMyAdmin も作成・起動しました。phpMyAdmin で MariaDB が正常に動作しているか確認しましょう。下記の URL にアクセスして下さい。

http://localhost:10111/

下の画像のようなページが表示されていたら OK です!

phpMyAdmin

これでデータベースの準備もできました。

User モデルを作成する

大半の Web アプリケーションはユーザ情報を格納したテーブルを作成するはずです。今回は users テーブルを作成してみましょう。users テーブルを作成するための User モデルを書きます。

現在のディレクトリ構成

├── Pipfile
├── Pipfile.lock
├── application
│   ├── __init__.py
│   ├── config.py
│   ├── database.py
│   └── models
│       ├── __init__.py
│       └── models.py
├── docker
├── docker-compose.yml
└── run.py

models/models.py

from datetime import datetime

from application.database import db


class User(db.Model):
    __tablename__ = 'users'

    __table_args__ = (
        db.UniqueConstraint('name'),
        db.UniqueConstraint('email'),
    )

    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(15, collation='utf8mb4_general_ci'), nullable=False)
    display_name = db.Column(db.String(50, collation='utf8mb4_general_ci'), nullable=False)
    email = db.Column(db.String(256, collation='utf8mb4_general_ci'), nullable=False)
    password = db.Column(db.String(1024, collation='utf8mb4_general_ci'), nullable=False)
    created_at = db.Column(db.DateTime, nullable=False, default=datetime.now)
    updated_at = db.Column(db.DateTime, nullable=False, default=datetime.now, onupdate=datetime.now)

    def __init__(self, name, display_name, email, password):
        self.name = name
        self.display_name = display_name
        self.email = email
        self.password = password

models/__init__.py

from .models import User

__all__ = [
    User,
]

application/__init__.py

from flask import Flask

from application.database import initialize_database
from application.models import User #追記


def create_app():
    app = Flask(__name__)
    app.config.from_object('application.config.Config')
    initialize_database(app)

    return app


app = create_app()

User モデルを元にテーブルを作成する

users テーブルを作成するための User モデルを書きました。次は Flask-Migrate を使用してマイグレーションを実行しましょう。database.py に 2 行だけ追記します。

database.py

from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate #追記

db = SQLAlchemy()


def initialize_database(app):
    db.init_app(app)
    Migrate(app, db) #追記

Flask-Migrate を使用してマイグレーションを実行する準備が整いました。下記のコマンドを順番に実行して下さい。

Virtualenv の有効化

pipenv shell

migrations ディレクトリの生成

FLASK_APP=run.py flask db init

マイグレーションファイルの作成

FLASK_APP=run.py flask db migrate

マイグレーションの実行

FLASK_APP=run.py flask db upgrade

上記のコマンド実行後、phpMyAdmin で users テーブルが作成されているか確認して下さい。

phpMyAdmin

上記のように users テーブルが問題なく生成されていたら OK です!

おわりに

この記事を通して、一人でも多くの人が詰まることなく、Flask で Web サービスの開発を始められたら嬉しいです!

著者

イセ ハヤト

ソフトウェアエンジニア

1994年、愛知生まれ富山育ち東京在住。中学時代、オンラインゲーム『メイプルストーリー』に熱中。課金するためにアフィリエイトを始める。大人買い出来るくらいにお金を稼ぎ、次第にゲームではなくインターネット自体に魅了される。大学時代、インカレプログラミングサークル『RE:CODE』で 2 人のエンジニアと出会う。UI/UX デザイナーとして彼らと手を組み、5 つのウェブサービスを開発。鳴かず飛ばずの結果に責任を感じ、チーム解散。プロダクトの成功確率を飛躍的に高められる人材に憧れを抱き、プロダクトマネージャーを志す。過去の開発経験からエンジニアリングの知識の乏しい人がウェブサービスを率いることの危険性を感じ、現在はソフトウェアエンジニアとして活動中。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です