0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

SQLModelをAlembicでmigrationした話し

Posted at

はじめに

FAST APIを使った簡易CRM実装の続きを記事にします。
今回は、SQLModelで定義したモデルをAlembicでmigrationした際の話しをまとめました。

過去記事(参考)

  1. FAST APIを使って簡易CRMを作った話し その1
  2. FAST APIを使って簡易CRMを作った話し その2
  3. FAST APIを使って簡易CRMを作った話し その3

おさらい

環境:
・macOS 12.6 Apple M1 Pro
・Python 3.12.7

models.pyを分割して、modelsフォルダを作成して各モデル毎にファイルを分割しました。

models
├── __init__.py
└── customer.py
__init__.py
from app.models.customer import Customer
customer.py
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接続情報を記述します。

alembic.ini
sqlalchemy.url = sqlite:///database.db

migrationsフォルダ内のenv.pyにSQLModelを使用するように記述します。
(#追記、#修正箇所)

env.py
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を指定することにより、SQLAlchemysa_column対して引数を渡すことができます。ここでは、データ更新時に現在時刻を渡したいので、onupdateに対してdatetime.nowで取得した値を設定しています。

models/base.py
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})
models/customer.py
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のリレーション等を中心にまとめたいと思います。
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?