Skip to content

Instantly share code, notes, and snippets.

@hdknr
Last active October 18, 2024 07:35
Show Gist options
  • Save hdknr/035130415a70830f3fe1a227f2d3cc61 to your computer and use it in GitHub Desktop.
Save hdknr/035130415a70830f3fe1a227f2d3cc61 to your computer and use it in GitHub Desktop.
alembic: マイグレーションツール

Alembic リレーション

Alembicを使ってマイグレーションを行う場合、SQLAlchemyのMappedを使ってモデルを定義することができます。 以下に、ParentChildモデルをMappedを使って定義する方法を示します。

まず、必要なモジュールをインポートします。

from sqlalchemy import create_engine, Column, Integer, String, ForeignKey
from sqlalchemy.orm import declarative_base, relationship, Mapped, mapped_column, sessionmaker

次に、ベースクラスを作成します。

Base = declarative_base()

ParentChildモデルをMappedを使って定義します。

class Parent(Base):
    __tablename__ = 'parents'
    
    id: Mapped[int] = mapped_column(Integer, primary_key=True)
    name: Mapped[str] = mapped_column(String)
    
    # 子モデルとのリレーションシップを定義
    children: Mapped[list["Child"]] = relationship("Child", back_populates="parent")

class Child(Base):
    __tablename__ = 'children'
    
    id: Mapped[int] = mapped_column(Integer, primary_key=True)
    name: Mapped[str] = mapped_column(String)
    parent_id: Mapped[int] = mapped_column(Integer, ForeignKey('parents.id'))
    
    # 親モデルとのリレーションシップを定義
    parent: Mapped["Parent"] = relationship("Parent", back_populates="children")

次に、データベースエンジンを作成し、テーブルを作成します。

engine = create_engine('sqlite:///example.db')
Base.metadata.create_all(engine)

最後に、セッションを作成し、データを追加してみます。

Session = sessionmaker(bind=engine)
session = Session()

# 親オブジェクトを作成
parent = Parent(name="Parent 1")

# 子オブジェクトを作成し、親に関連付け
child1 = Child(name="Child 1", parent=parent)
child2 = Child(name="Child 2", parent=parent)

# セッションに追加してコミット
session.add(parent)
session.add(child1)
session.add(child2)
session.commit()

これで、ParentChildの間に1対多の関係が定義され、データベースに保存されます。 Alembicを使ってマイグレーションを行う際には、モデルの変更を反映するためにマイグレーションスクリプトを生成し、適用する必要があります。

stamp

stamp コマンド

Alembicでマイグレーションを「fake」で適用するには、alembic stamp コマンドを使用します。このコマンドは、実際にマイグレーションを実行せずに、データベースのマイグレーション履歴を更新します。以下の手順で行います:

  1. マイグレーションスクリプトを作成: まず、通常通りマイグレーションスクリプトを作成します。

    alembic revision --autogenerate -m "add new table"
  2. マイグレーションを「fake」で適用: 次に、alembic stamp コマンドを使用して、データベースのマイグレーション履歴を更新します。

    alembic stamp head

    これにより、データベースのスキーマは変更されませんが、Alembicのマイグレーション履歴は最新のリビジョンに更新されます。

  3. 特定のリビジョンに「fake」で適用: 特定のリビジョンに「fake」で適用したい場合は、リビジョンIDを指定します。

    alembic stamp <revision_id>

これで、マイグレーションを実行せずに履歴を更新することができます。これにより、既存のデータベースに対して新しいマイグレーションを適用する際に、データの変更を避けることができます。

¹²(https://nikaera.com/archives/pytest-sqlalchemy-alembic/)

初期化

Alembicを使ってデータベース定義をそのままにして、マイグレーションファイルだけを初期化することは可能です。以下の手順で行うことができます:

  1. 既存のマイグレーションファイルを削除:

    • migrations/versions フォルダ内のすべてのファイルを削除します。
  2. 新しいベースリビジョンを作成:

    • 新しいベースリビジョンを作成するために、以下のコマンドを実行します。

      alembic revision --autogenerate -m "base revision"
  3. データベースの状態をリセット:

    • データベースの状態をリセットするために、以下のコマンドを実行します。

      alembic stamp head

これにより、データベースの現在の状態を反映した新しいベースリビジョンが作成され、マイグレーションファイルが初期化されます¹²

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment