Help us understand the problem. What is going on with this article?

Flask + SQLAlchemyプロジェクトを始める手順

More than 1 year has passed since last update.

いつも行っていることをまとめる。

参考にするドキュメント

今回の利用した環境は以下の通り。

  • MacOS 10.13.3
  • Python 3.6.3
  • flask 0.12.2
  • flask-sqlalchemy 2.3.2
  • PyMySQL 0.8.0
  • SQLAlchemy 1.2.2

必要なライブラリをインストールする

  • flask
  • SQLAlchemy
  • flask-sqlalchemy
  • pymysql

をインストールする。

$ pip install flask SQLAlchemy flask-sqlalchemy PyMySQL

アプリ初期構築

アプリの初期構築を行う。
Flaskは自由度が高いのでアプリのディレクトリ構成は様々な形を取ることができるが、以下はその一例。この例に沿って以下話を進める。

├── flask_sample
│   ├── app.py
│   ├── config.py
│   └── database.py
└── run.py
  • flask_sample/database.py
"""FlaskアプリがSQLAlchemyを使えるようにするための初期化"""
from flask_sqlalchemy import SQLAlchemy

db = SQLAlchemy()


def init_db(app):
    db.init_app(app)
  • flask_sample/config.py
"""FlaskのConfigを提供する"""
import os


class DevelopmentConfig:

    # Flask
    DEBUG = True

    # SQLAlchemy
    SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://{user}:{password}@{host}/flask_sample?charset=utf8'.format(**{
        'user': os.getenv('DB_USER', 'root'),
        'password': os.getenv('DB_PASSWORD', ''),
        'host': os.getenv('DB_HOST', 'localhost'),
    })
    SQLALCHEMY_TRACK_MODIFICATIONS = False
    SQLALCHEMY_ECHO = False


Config = DevelopmentConfig

※1 上記の SQLALCHEMY_DATABASE_URI は、DriverにPyMySQLを利用した場合の書き方になっている。PyMySQLとは別のDriverを用いる場合は別の設定にする必要がある。詳しくはリンク先ページ参照。 http://docs.sqlalchemy.org/en/latest/dialects/mysql.html
※2 今回Database名を flask_sample としている。当然MySQLからCREATE DATABASE文を使ってDatabaseを先に作っておく必要がある。(Databaseの作成方法は割愛)

  • flask_sample/app.py
"""flask appの初期化を行い、flask appオブジェクトの実体を持つ"""
from flask import Flask

from flask_sample.database import init_db


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

    init_db(app)

    return app

app = create_app()
  • run.py
from flask_sample.app import app


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

このアプリを起動する場合は、以下のコマンドを実行する。

$ python run.py

あるいは環境変数FLASK_APPを定義してflaskコマンドを利用することでもアプリを起動することができる。

$ FLASK_APP=run.py flask run

これでFlaskでSQLAlchemyを利用する基本的な準備は整った。

Modelを一つ作ってみる

実際にModelクラスを一つ作ってみることにする。

Modelクラスの定義

以下のように flask_sample/models 以下を用意する。

flask_sample

├── app.py
~
└── models
    ├── __init__.py
    └── models.py
  • flask_sample/models/models.py
from datetime import datetime
from flask_sample.database import db


class User(db.Model):

    __tablename__ = 'users'

    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(255), 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)
  • flask_sample/models/__init__.py
from .models import User


__all__ = [
    User,
]

そして、appがロードされた時にこのUserクラスもloadされるように、flask_sample/app.py内でUserクラスをimportするようにする。

from flask import Flask
from flask_sample.database import init_db
import flask_sample.models

...

テーブルの作成

※2019/01/03追記
この直後に説明する Flask-Migrate を使ったMigrationを実施する場合は、ここで説明している db.create_all() を使ったテーブルの作成は行うべきではありません。
Flask-Migrate ではテーブルの状態管理をしており、 Flask-Migrate を使わずにテーブル作成した場合、未知の状態を与えてしまうためです。もし、 Flask-Migrate を利用する予定の場合はこの項の説明を読み飛ばして次の説明を読み進めることをおすすめします。

参考issue
https://github.com/miguelgrinberg/Flask-Migrate/issues/173

Modelクラスを用意したら、次にDatabaseにテーブルを作成する。
テーブルを作成するには SQLAlchemy.create_all() を呼び出す。これでimportされているModelクラスのテーブルが全て作成される。

$ FLASK_APP=run.py flask shell
Python 3.6.3 (default, Jan  8 2018, 18:42:55)
[GCC 4.2.1 Compatible Apple LLVM 9.0.0 (clang-900.0.39.2)] on darwin
App: flask_sample.app [debug]
Instance: ~/flask-sample/instance
>>> from flask_sample.database import db
>>> db.create_all()

これで users テーブルが作成された。

migrationを行うには

直前の手順で、定義しているModelクラスに関するテーブルが作成されたわけだが、都度手動で db.create_all() を呼び出してテーブルを定義するには少し面倒が多く、きちんとschemaのバージョン管理を行うことも含めてMigrationの導入を行う。

Flask + SQLAlchemy でMigrationを行うには Flask-Migrate を使うと便利。

Flask-Migrateのインストール

pipでインストール可能。

$ pip install Flask-Migrate

Flask-Migrateを使う

Flask-Migrateを使うには、flask_migrate.Migrate にflaskオブジェクトと flask_sqlalchemy.SQLAlchemy オブジェクトを食わせることでFlask-MigrateのCLIコマンドを使うことが可能になる。以下は上記までのサンプル上でFlask-Migrateを使う場合の例。

  • flask_sample/database.py
"""FlaskアプリがSQLAlchemyとFlask-Migrateを使えるようにするための初期化"""
from flask_sqlalchemy import SQLAlchemy

from flask_sample.database import init_db

from flask_migrate import Migrate  # 追加

db = SQLAlchemy()


def init_db(app):
    db.init_app(app)
    Migrate(app, db)  # 追加

こうした後では flask db コマンドが利用可能になる。

$ FLASK_APP=run.py flask db init

Flask-Migrateのコマンド例

最低限のコマンド例を示す。

https://flask-migrate.readthedocs.io/en/latest/#command-reference
こちらにコマンドリファレンスがあるので、これで利用可能なコマンドの全貌がわかる。

※以下のコマンド例は環境変数 FLASK_APP を適切に設定している場合における場合。

初期化

$ flask db init

migrationsディレクトリが作成され、その中で必要なファイルが設置される。

migrationファイルの作成

$ flask db migrate

modelクラスの定義を見て、差分をmigrationファイルとして作成する。(まだmigrationの適用はされない)

migrationの実行

$ flask db upgrade

未実行のmigrationを実行する。

migrationのrollback

$ flask db downgrade

一つ前のバージョンに戻す。

まとめ

  • Flaskアプリの初期構築
  • Flask-SQLAlchemyの使い方(Model定義)
  • Flask-Migrateの使い方

を簡単に説明した。これでベーシックなFlask + SQLAlchemyを使ったアプリケーション構築のための準備が整った。
追加でこれをしていくといいよ、というのがあればどしどし。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away