もくじ
はじめに
前回→VPSを使ってウェブアプリを作りたい2(Github ActionsでCI/CD)
もう少し開発環境を整えていく。
- 環境管理:
.env
+python-dotenv
でシークレット/設定を一元管理 - DBマイグレーション:SQLAlchemy + Alembic を導入(Flask-SQLAlchemy とFlask-Migrate)
- CI/CD拡張:CI に Linter(flake8 or black)、型チェック(mypy)、Coverage レポート を追加。CD に「マイグレーション実行」「ヘルスチェック」「ロールバック条件」ステップを追加
- ドキュメント整備:README に「開発手順」「CI/CD フロー」「環境変数一覧」を明記
環境管理とDBマイグレーション
1 .env
と .env.example
を用意する
プロジェクトルートに .env
を作成し、機密情報や環境ごとに変わる設定だけを置く。
gitには上げない。 PostgreSQLインストールはこちら
# .env
FLASK_ENV=development
SECRET_KEY="ランダムな長い文字列"
DATABASE_URL=postgresql://myapp_user:password@localhost:5432/myapp_db
同じく 雛形としてキー名だけのgit管理用の.env.example
を作る
# .env.example
FLASK_ENV=
SECRET_KEY=
DATABASE_URL=
.gitignore
に以下を追加して、.env
は Git管理から外す。.env.exampleはGit管理のまま
.env
!.env.example
必要ライブラリのインストール
pip install python-dotenv Flask-SQLAlchemy Flask-Migrate psycopg2-binary
python-dotenv
….env
から環境変数をロードできるFlask-SQLAlchemy
… SQLを使わずにDBを操作できるSQLAlchemyのFlask連携版Flask-Migrate
… DB変更履歴を管理できるAlembicのFlask連携版psycopg2-binary
… PostgreSQL ドライバ
ライブラリを追加したら、requirements.txtに追加しておく
pip freeze > requirements.txt
.env
の読み込みテスト
環境変数を正しく読み込めるか確認 tests/test_env.pyを作って以下を入力
import os
from dotenv import load_dotenv, find_dotenv
def test_env_loading():
# プロジェクトルートの .env を読み込む
dotenv_path = find_dotenv(".env", raise_error_if_not_found=True)
load_dotenv(dotenv_path)
# DATABASE_URL が設定されていることを確認
assert os.getenv("DATABASE_URL") is not None
# 必要なら値の形式チェック(postgresql://で始まっている文字列かチェック)
assert os.getenv("DATABASE_URL").startswith("postgresql://")
pytestでチェック
python -m pytest
app.py
を修正
import os
from dotenv import load_dotenv
from flask import Flask
# 1) .env をロード
basedir = os.path.abspath(os.path.dirname(__file__))
load_dotenv(os.path.join(basedir, ".env"))
app = Flask(__name__)
# 2) 設定を環境変数から
app.config["SECRET_KEY"] = os.getenv("SECRET_KEY", "change-me")
app.config["SQLALCHEMY_DATABASE_URI"] = os.getenv("DATABASE_URL")
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
# 3) ORM とマイグレーションを初期化
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
db = SQLAlchemy(app)
migrate = Migrate(app, db)
@app.route("/")
def index():
return "Hello, myapp!"
if __name__ == "__main__":
app.run(debug=True)
モデルファイルを用意
データベースに格納する情報のモデル(規格のようなもの)を設定する。
# models.py
from app import db
from werkzeug.security import generate_password_hash, check_password_hash
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(64), unique=True, nullable=False)
pwd_hash = db.Column(db.String(128), nullable=False)
# 平文のパスワードpwをハッシュ(暗号)化して保存
def set_password(self, pw):
self.pwd_hash = generate_password_hash(pw)
# 入力された平文のパスワードpwが保存してあるハッシュと一致するかチェック
def check_password(self, pw):
return check_password_hash(self.pwd_hash, pw)
primary_key=True
:主キーとして自動採番unique=True
:同じユーザー名を二度登録できない一意制約nullable=False
:空(NULL)を禁止
app.pyにモデルを読み込むコードを記入
import os
from dotenv import load_dotenv
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
# .env を読み込む
basedir = os.path.abspath(os.path.dirname(__file__))
load_dotenv(os.path.join(basedir, ".env"))
# Flask アプリの生成と設定
app = Flask(__name__)
app.config["SECRET_KEY"] = os.getenv("SECRET_KEY", "change-me")
app.config["SQLALCHEMY_DATABASE_URI"] = os.getenv("DATABASE_URL")
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
# ORM/マイグレーション用オブジェクトを初期化
db = SQLAlchemy(app)
migrate = Migrate(app, db)
#------------ここから追加分---------
# models.py を読み込む
import models
#------------ここまで追加分---------
@app.route("/")
def index():
return "Hello, myapp!"
if __name__ == "__main__":
app.run(debug=True)
Flask CLI の設定
ターミナルでflaskコマンドを使うために設定を読み込む。 .envに記入済みの場合は無くてもいいかもしれない
export FLASK_APP=app.py
export FLASK_ENV=development
マイグレーション初期化
データベースの履歴管理のためのmigrateフォルダの初期設定
flask db init
プロジェクト直下に migrations/
ディレクトリが作成され、中に alembic.ini
や env.py
などが生成される
初回マイグレーションの作成・適用
flask db migrate -m "initial schema"
flask db upgrade
models.pyの定義に沿ってカラムが作られる。
データベースが正しく作成されているかチェック
psql -d myapp_db -c "\dt"
モデルが循環参照になっていてうまくいかない時
モデルのForeignKey
定義にuse_alter=True
を指定すると、Alembic が
- テーブル本体をまず作成
- その後で
ALTER TABLE … ADD CONSTRAINT …
で FK を追加
という 2 ステップに分けてマイグレーションスクリプトを生成してくれる
スポンサーリンク