はじめに
FAST APIを使った簡易CRM実装の続きを記事にします。
今回は、SQLModelで定義したモデルをAlembicでmigrationした際の話しをまとめました。
過去記事(参考)
おさらい
環境:
・macOS 12.6 Apple M1 Pro
・Python 3.12.7
models.pyを分割して、modelsフォルダを作成して各モデル毎にファイルを分割しました。
models
├── __init__.py
└── customer.py
from app.models.customer import Customer
from sqlmodel import SQLModel, Field
class Customer(SQLModel, table=True):
id: int | None = Field(default=None, primary_key=True)
name: str = Field(index=True)
address: str = Field(default=None)
Alembicを使ってmigrationをする
今回参考にした記事はこちらです。
$ poetry add alembic
$ alembic --version
alembic 1.14.0
環境の初期化
$ alembic init migrations
各ファイルの更新
migrations
フォルダ内のalembic.ini
のDB接続情報を記述します。
sqlalchemy.url = sqlite:///database.db
migrations
フォルダ内のenv.py
にSQLModelを使用するように記述します。
(#追記、#修正箇所)
from logging.config import fileConfig
from sqlalchemy import engine_from_config
from sqlalchemy import pool
from alembic import context
from app.models import Customer # 追加
from sqlmodel import SQLModel # 追加
# this is the Alembic Config object, which provides
# access to the values within the .ini file in use.
config = context.config
# 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 = SQLModel.metadata # 修正
# other values from the config, defined by the needs of env.py,
# can be acquired:
# my_important_option = config.get_main_option("my_important_option")
# ... etc.
Modelからmigrationする
以下のコマンドでmigrationファイルを作成します。
-m
以降に指定した文字列でmigrations/versions
フォルダ配下にファイルが作成されます。
$ alembic revision --autogenerate -m "customer"
DBに適用します。
$ alembic upgrade head
Modelを修正する
作成日と更新日を追加したかったので、共通で使用するModelをbase.py
として
切り出すようにしました。
updated_at
の際に行っているsa_column_kwargs
を指定することにより、SQLAlchemy
のsa_column
対して引数を渡すことができます。ここでは、データ更新時に現在時刻を渡したいので、onupdate
に対してdatetime.now
で取得した値を設定しています。
from datetime import datetime
from sqlmodel import SQLModel, Field
class Base(SQLModel):
created_at: datetime = Field(default_factory=datetime.now, nullable=False)
updated_at: datetime = Field(
default_factory=datetime.now, nullable=False,
sa_column_kwargs={'onupdate': datetime.now})
from sqlmodel import Field
from backend.app.models.base import Base
class Customer(Base, table=True): # SQLModelからBaseへ変更
id: int | None = Field(default=None, primary_key=True)
name: str = Field(index=True)
address: str = Field(default=None)
migrationファイルの作成と更新をします。
$ alembic revision --autogenerate -m "add_base_model"
$ alembic upgrade head
まとめ
- Djangoのmigrationと比べてファイルの初期設定は必要でしたが、それほど遜色なく使えそうです。次回はSQLModelについて複数Modelのリレーション等を中心にまとめたいと思います。