Python/sqlalchemyでテーブルをバージョン管理するalembicで困ったとき


前提

使い方、導入の仕方などはこちらの記事がが非常に有用でしたのでご参照ください。

この記事では使い方ではなく困った時の解決法などをいくつか書いていきます。また、随時更新します。

競合が起こった時

gitでもよくあることですがチームでバージョン管理していると競合が起こります。

alembic history --verbose

こちらのコマンドでheadリビジョンを確認することができます。

バージョンはRivision IDで管理しているので競合を起こしているリビジョンのpyファイルを退避させましょう。

alembic upgrade head

でテーブルが最新リビジョンと相違ない状態になったらsqlalchemyで定義してあるテーブルと退避させたpyファイルの相違している部分を修正し、

alembic revision --autogenerate

しましょう。
alter文でつくられたリビジョンが生成されるので再度

alembic upgrade head

で目的のリビジョンを反映させることができます。

headが2つ存在してしまった場合

例えばですが

alembic upgrade head

をすることがないまま

alembic revision --autogenerate -m "create tables"

を2回してしまった場合、headリビジョンが2つ存在してしまうという状況になります。
もちろんこのように単純なケースであれば古い方のリビジョンのpyファイルを消してしまえば解決するのですが、それぞれのリビジョンから派生して複数のalter_table.pyがつくられてしまった場合、後に

alembic upgrade head

すると

FAILED: Multiple head revisions are present for given argument 'head'; please specify a specific target revision, '<branchname>@head' to narrow to a specific head, or 'heads' for all heads

というエラーメッセージが出ます。headを1つにしてくださいという意味ですね。

じゃあリビジョンを指定してあげて...

alembic revision -m "hogehoge"

としたところで

FAILED: Multiple heads are present; please specify the head revision on which the new revision should be based, or perform a merge.

と出てしまう。

実はheadの管理って

revision = 'hoge'
down_revision = None

ここでしてるんですよね。

なので

revision = 'hoge'
down_revision = 'fuga'

と指定してあげましょう。

そうするとhogeがheadに、fugaが1つ前のリビジョンになります。

あとは

alembic upgrade head

すればいいだけです。

autogenerateでカラムの型変更が検出されない時の解決方法

env.pyの
context.configure
に、

compare_type=True

を追加してあげましょう。
その後

alembic revision --autogenerate

すれば検出してくれます。