FastAPI + SQLAlchemy + Alembic + SQLiteでマイグレーション
FastAPI + SQLAlchemy + Alembic + SQLiteでマイグレーション FastAPIにはデータベースのマイグレーション機能はありませんが、Alembicというデータベースのマイグレーションツー […]
Filter by Category
FastAPI + SQLAlchemy + Alembic + SQLiteでマイグレーション FastAPIにはデータベースのマイグレーション機能はありませんが、Alembicというデータベースのマイグレーションツー […]
AWS LambdaとS3、SNSでファイルのアップロードを自動通知 AWS Lambdaは特定の条件を満たすときにサーバーレスでPython(他のプログラミング言語も)を実行できるサービスです。トリガーを検知したときや […]
GitHubリポジトリを別のOrganizationに移行 非公開用のOrganization(組織)で管理していたリポジトリの公開範囲をプライベートから公開に変更するにあたって、リポジトリを別のOrganization […]
PythonとMoviePyで動画ファイルの指定時間ごとの分割を自動化 OpenCVなどで動画の処理を行う際に、1分毎の変化や10分毎に結果を見たいときに一連の動画から指定した時間毎に分割して切り出したいことがあります。 […]
OpenCVで動画ファイルの最終フレームを取得 PythonとOpenCVを使用して動画ファイルの最大フレーム数を取得する方法を解説をします。処理の確認用に取得した最大フレーム数とファイル名をソートして表示させます。 コ […]
Amazon Route 53で新規ドメインを登録 ウェブサイトやウェブサービスを運営する際にドメインは欠かせない要素です。この記事では、Amazon Route 53で新しいドメインを登録する方法について解説します。 […]
GitHub CopilotをPyCharmで使用するまでの手順 GitHub Copilotは、プログラミングの効率を飛躍的に向上させるツールで、開発者にとって非常に便利なコーディングのサポートを提供します。本記事では […]
PyCharm 2023.2から追加されたBlackによるコード成形 Pythonのコード成形で人気のBlackがPyCharm 2023.2から環境設定画面で設定可能になりました。従来はpipなどでインストールしていま […]
S3のライフサイクルルールの落とし穴 保存したデータが必要以上に増えないようにライフサイクルルールで指定した日数を経過したデータは削除する設定にしていましたが、後日改めてバケットを確認するとフォルダ、ファイルどちらも削除 […]
S3でストレージクラスを一括で変更 デフォルトではS3のストレージクラスは「標準」になっていますが、このストレージクラスは頻繁にアクセスするデータを保存するのに適した設定なので、バックアップファイルなどの頻繁にアクセスし […]
request.FILES.get(‘file’)とrequest.FILES[‘file’] の違い この記事は生成AIで作成されました request.FILES.ge […]
Twitter APIの変更に関して 最近、Twitter APIのバージョンがアップデートされ、v1が廃止されました。これに伴い、開発者はv2への移行が必要となります。 Twitter v1の廃止 Twitter v1 […]
AWS Rekognitionとは AWS Rekognitionは、画像と動画から情報を抽出するディープラーニング技術を利用した分析サービスです。このサービスは、顔認識、物体検出、シーン分析など、さまざまな分析機能を提 […]
タイプヒント, コメント, ドックストリングの追記とGitHubでのコンフリクト コメントの記述方法と注意点 タイプヒントの記述方法と注意点 ドックストリングの記述方法と注意点 GitHubのコンフリクト発生時の対処法に […]
VSCodeとGitでのコード管理 行ったこと アクセストークンの取得リポジトリのクローン リポジトリのクローン ブランチの作成 ファイルのコミット 同期 ターミナルでのgitbashの利用(windows) 作業用のブ […]
vue createで作成する際に.gitが生成されないようにする Vue.jとDjangoのプロジェクトをGitで管理しようとしたところ、vue createで生成したディレクトリだけが追加されていないことがわかりまし […]
Vue.jsとDjango REST Frameworkで画面が真っ白になる原因〜2〜 Django REST Frameworkと組み合わせたVue.jsで、ビルド後にバックエンドの開発サーバー(8000ポートなど)で […]
Vue.jsとDjango REST Frameworkで画面が真っ白になる原因〜1〜 画面が真っ白になる原因 Vue.jsとDjangoの組み合わせで開発中にnpm run serveで起動した開発サーバーでページを確 […]
Vue.jsとDjango REST FrameworkでSPA構築〜後半〜 前半に続き、後半はフロントエンド側(Vue.js)の実装を進めていきます。 コードはGitHubリポジトリにあげています。 開発環境 PC: […]
Vue.jsとDjango REST FrameworkでSPA構築〜前半〜 Vue.jsとFlaskの連携に続き、今回はVue.jsとDjango(Django REST Framework)の連携を解説します。チュー […]
FastAPIにはデータベースのマイグレーション機能はありませんが、Alembicというデータベースのマイグレーションツールがあり、マイグレーションファイルを自動で生成できます。本記事ではORMのSQLAlchemyと組み合わせてデータベースのマイグレーションの仕方について解説します。
PC: MacBook Pro (14, 2021)
OS: macOS Monterey 12.6.7
Python: 3.10.0
FastAPI: 0.104.1
Alembic: 1.13.0
SQLAlchemy: 2.0.23
SQLAlchemy-Utils: 0.41.1
.
├── alembic.ini
├── database.py
├── migrations
│ ├── README
│ ├── env.py
│ ├── script.py.mako
│ └── versions
│ ├── 2637abbcf5c1_create_tables.py
│ └── d75d243cebd5_add_age_column.py
├── models
│ ├── mixins.py
│ └── users.py
├── test.db
└── test_main.http
FastAPIは既にインストール済みの状態で、マイグレーションに必要なパッケージのインストールを下記のコマンドで実行します。
pip install alembic SQLAlchemy SQLAlchemy-Utils
Alembic:SQLAlchemyのマイグレーションツール
SQLAlchemy:データベースを操作するORM(Object Relational Mapper)
SQLAlchemy-Utils:SQLAlchemyのユーティリティ関数
下記のコマンドを実行すると、alembic.ini、env.pyなどが入ったmigrationsというディレクトリが生成されます。
alembic init migrations
tree
でディクトリ構造を表示させると下記のようになっています。
.
├── alembic.ini
└── migrations
├── README
├── env.py
├── script.py.mako
└── versions
alembic.ini
...
# the output encoding used when revision files
# are written from script.py.mako
# output_encoding = utf-8
sqlalchemy.url = sqlite:///test.db
[post_write_hooks]
# post_write_hooks defines scripts or Python functions that are run
# on newly generated revision scripts. See the documentation for further
# detail and examples
...
データベースの設定を行うdatabase.pyを作成します。
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker, declarative_base
# データベースURL(SQLiteの場合)
SQLALCHEMY_DATABASE_URL = "sqlite:///test.db"
# SQLAlchemy エンジンの作成
engine = create_engine(
SQLALCHEMY_DATABASE_URL, connect_args={"check_same_thread": False}
)
# セッションの作成
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
Base = declarative_base()
def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()
modelsディレクトリにユーザー情報のusers.pyと共通機能のmixins.pyの2つのSQLAlchemyのモデルを作成します。マイグレーションの確認だけであればusers.pyのみで問題ないですが、実際のアプリケーション開発を想定して2つのモデルを用意します。
models/users.py
from sqlalchemy import Column, Integer, String
from sqlalchemy_utils import UUIDType
from uuid import uuid4
from database import Base
from .mixins import TimestampMixin
class User(Base, TimestampMixin):
__tablename__ = 'users'
id = Column(Integer, primary_key=True)
uuid = Column(UUIDType(binary=False), nullable=False, default=uuid4)
name = Column(String)
fullname = Column(String)
mixins.pyのTimestampMixinを継承しているので作成日時と更新日時のカラムも作成されます。
models/mixins.py
from sqlalchemy import Column, DateTime, func
class TimestampMixin(object):
created_at = Column(DateTime, default=func.now(), nullable=False, comment="作成日時")
updated_at = Column(DateTime, default=func.now(), onupdate=func.now(), nullable=False, comment="更新日時")
TimestampMixinはusers.pyのUserクラスのように継承させることで作成日時と更新日時のカラムを作成します。
from logging.config import fileConfig
from sqlalchemy import engine_from_config
from sqlalchemy import pool
from alembic import context
# 追記
from database import Base
import models.users # noqa: F401
import models.mixins # noqa: F401
...
# Interpret the config file for Python logging.
# This line sets up loggers basically.
if config.config_file_name is not None:
fileConfig(config.config_file_name)
# add your model's MetaData object here
# for 'autogenerate' support
# from myapp import mymodel
# target_metadata = mymodel.Base.metadata
# 修正
target_metadata = Base.metadata
...
# noqa: F401はエラー対策用に記載
下記のコマンドでcreate tablesという名前のマイグレーションファイルを作成します。
alembic revision --autogenerate -m "create tables"
INFO [alembic.runtime.migration] Context impl SQLiteImpl.
INFO [alembic.runtime.migration] Will assume non-transactional DDL.
INFO [alembic.autogenerate.compare] Detected added table 'users'
migrations/versionsにマイグレーションファイル(2637abbcf5c1_create_tables.py)が生成されていれば成功です。
今回はUserクラスのuuidカラムにUUIDを指定しているため、そのままalembic upgrade head
でマイグレーションを実行すると下記のエラーが発生してしまうので予め修正しておきます。(UUIDを使用していない場合はsqlalchemy_utilsのインポートは必要ありません。)
sa.Column('uuid', sqlalchemy_utils.types.uuid.UUIDType(binary=False), nullable=False),
NameError: name 'sqlalchemy_utils' is not defined
2637abbcf5c1_create_tables.py(alembic revision –autogenerate -m “create tables”を実行した際にmigrations/versions内に生成されたマイグレーションファイル)
from typing import Sequence, Union
from alembic import op
import sqlalchemy as sa
# 追記
import sqlalchemy_utils
...
import sqlalchemy_utils
を追記します。
改めて下記のコマンドでマイグレーションを実行してデータベースに内容を反映します。
alembic upgrade head
INFO [alembic.runtime.migration] Context impl SQLiteImpl.
INFO [alembic.runtime.migration] Will assume non-transactional DDL.
INFO [alembic.runtime.migration] Running upgrade -> 2637abbcf5c1, create tables
テーブルが追加されました。
エディタのツールやデータベースのアプリなどで画像のようにusersテーブルが確認できればマイグレーション成功です。
users.pyにageカラムを追記してマイグレーションファイルを作成します。
fullname = Column(String)
# 追加
age = Column(Integer)
alembic revision --autogenerate -m "add age column"
migrations/versionsにマイグレーションファイル(d75d243cebd5_add_age_column.py)が生成されていれば成功です。続けて下記のコマンドでマイグレーションを実行します。
alembic upgrade head
INFO [alembic.runtime.migration] Context impl SQLiteImpl.
INFO [alembic.runtime.migration] Will assume non-transactional DDL.
INFO [alembic.runtime.migration] Running upgrade -> 2637abbcf5c1, create tables
INFO [alembic.runtime.migration] Running upgrade 2637abbcf5c1 -> d75d243cebd5, add age column
画像のようにageカラムが追加されていれば成功です。
データベースを前の状態に戻したいときは下記のコマンドで戻せます。-1で1つ前の状態、-2で2つ前の状態に戻せます。反対に新しい状態にする際は+1、+2で指定できます。
alembic downgrade -1
INFO [alembic.runtime.migration] Context impl SQLiteImpl.
INFO [alembic.runtime.migration] Will assume non-transactional DDL.
INFO [alembic.runtime.migration] Running downgrade d75d243cebd5 -> 2637abbcf5c1, add age column
画像のようにageカラムの追加前の状態に戻せていれば成功です。
現在のバージョンを出力
alembic current
出力結果
INFO [alembic.runtime.migration] Context impl SQLiteImpl.
INFO [alembic.runtime.migration] Will assume non-transactional DDL.
d75d243cebd5 (head)
リビジョンID、元のリビジョンID、作成日などを出力
alembic history --verbose
出力結果
Rev: d75d243cebd5 (head)
Parent: 2637abbcf5c1
Path: /DIRPATH/migrations/versions/d75d243cebd5_add_age_column.py
add age column
Revision ID: d75d243cebd5
Revises: 2637abbcf5c1
Create Date: 2023-12-05 13:37:36.048555
...
データベースの初期化
alembic downgrade base
群馬県でPythonを使ったAIやソフトウェアを開発している株式会社ファントムが運営しています。
メーリングリストに登録するとファントムの最新情報をお届けします
お客様のメールアドレスを共有することはありません