1つのDBを複数のalembicで管理する

とあるところでAPIを作ることになったんですが、同じユーザーが使うものではあっても1つのAPIサーバで作るにはジャンルが異なっていて微妙なケースがありました。

もちろん複数のDBを用意してもよいのですが、それはそれでDBのバックアップとか管理がめんどくさいなぁということで、1つのDB(Postgres)を2つのFastAPIで使うような形を作ってみました。

スキーマを使わない場合

env.pyを下記のように編集

# 追加
def include_object(object, name, type_, reflected, compare_to):
    if type_ == 'table' and object.schema != None:
        return False

    return True

# 変更
def run_migrations_online():
...
    with connectable.connect() as connection:
        context.configure(
            connection=connection,
            target_metadata=target_metadata,
            include_schemas=True, # 追加
            include_object=include_object # 追加
        )

この変更をしたenv.pyをalembicで読み込ませるとスキーマ無し(Public)のみバージョン管理をするようになります。

スキーマを使う場合

## スキーマ名がsome_schemaの場合
# 追加
def include_object(object, name, type_, reflected, compare_to):
    if type_ == 'table' and object.schema != "some_schema":
        return False

    return True

# 変更
def run_migrations_online():
...
    with connectable.connect() as connection:
        context.configure(
            connection=connection,
            target_metadata=target_metadata,
            include_schemas=True, # 追加
            include_object=include_object # 追加
            version_table_schema="some_schema" # 追加
        )

スキーマごとにalembic_versionテーブルが作成され、個別に管理できます。

似たようなことができるinclude_nameという関数もあるのでそちらを使ってもいいかもしれません。

ちなみにalembicのautogenerateではスキーマの作成はやってくれないので、手動でupgradeとdowngradeに追加するとよいと思います。

def upgrade():
    op.execute("create schema some_schema")
    ...

def downgrade():
    ...
    op.execute("drop schema some_schema")



この記事が気に入ったらサポートをしてみませんか?