マイグレーション用のupgrade,downgradeスクリプトを手書きとかして疲弊したくないので、Alembicを導入してみたメモ。
AlembicはSQLAlchemyのマイグレーション用スクリプトとサーバの状態から、upgrade,downgrade差分を自動で生成してくれる素敵なツールです。
#インストール
導入はpipで終わります
pip install sqlalchemy
pip install alembic
お使いのSQLに合わせて、python用SQLドライバーを入れておく必要があります(サーバとの差分を取るため、SQLサーバと接続できる必要があります)
今回はMySQLで使用しました。
pip install pymysql
#初期設定
alembic initコマンドで、作業用ディレクトリを作成します。
alembic init [作業ディレクトリ名]
alembic.iniファイルと指定した作業ディレクトリが作成されます。作業ディレクトリの中にはenv.pyという設定ファイルが有りますので、このファイルとalembic.iniの2つのファイルを編集します。
まず、alembic.iniはMySQLへの接続の設定を記述します。sqlalchemy.urlのところを書き換えます。
sqlalchemy.url = mysql+pymysql://ユーザー名:パスワード@ホスト名:ポート/DB名
※:ポート名は省略可能
DB名まで指定が必要です。このiniファイルは複数用意しておいて実行時に使い分けることができるので、DBごとにiniファイルを用意しておくことで対応できます。
続いて、作業ディレクトリの中のenv.pyを書き換えます。# add your model's MetaData object hereというコメント行があるので、その下にtarget_metadataという変数に対してSQLAlchemy用のDB定義用スクリプトのMetaDataクラスのインスタンスを登録します。
ちょっとわかりにくいかもしれませんので、まずは、サンプルのSQLAlchemy用のDB定義スクリプト
from sqlalchemy import MetaData, Table, Column, Integer, String, DateTime, Float, Boolean, Text
from sqlalchemy.dialects.mysql import TINYINT, SMALLINT
meta = MetaData()
Table(
'status', meta,
Column('account_id', Integer, primary_key=True, autoincrement=False),
Column('hp', SMALLINT, nullable=False, server_default='30'),
Column('weapon_id', SMALLINT, nullable=False, server_default='1'),
Column('weapon_lv', TINYINT, nullable=False, server_default='0'),
Column('armor_id', SMALLINT, nullable=False, server_default='1'),
Column('armor_lv', TINYINT, nullable=False, server_default='0'),
)
というのがあったとして、
# add your model's MetaData object here
# for 'autogenerate' support
# from myapp import mymodel
# target_metadata = mymodel.Base.metadata
import sample
target_metadata = sample.meta
というように記述します。
#マイグレーション用スクリプト生成
sample.pyファイルをimportするため、ファイルのある場所をPYTHONPATHに指定する必要があります。カレントにある場合も、.の指定が必要です。
PYTHONPATH=. alembic revision --autogenerate
alembic.iniを複数用意する場合、ファイル名を変えたのち--configオプションで指定します。
PYTHONPATH=. alembic --config iniファイル revision --autogenerate
--autogenerateをつけることによって、作業ディレクトリの中のversionsというディレクトリの中に、現在のサーバと指定したSQLAlchemyスクリプトとで差分をとって、upgrade,downgradeを含んだスクリプトを自動生成してくれます。
後は、iniファイルで指定したマイグレーションの元となるファイルを編集しては、alembic revisionコマンドで差分ファイルを生成していきます。
間違えて変な設定するスクリプト作っちゃっても、作ったばかりなら生成されたファイルを消すだけでなかったことにできます。
※downgrade用に前バージョンのファイル名が記述されているので、途中のファイルを消すときは修正が必要
#サーバに適用
alembic revisionで作ったスクリプトはalembic upgradeを使ってサーバに適用することができます。upgradeやdowngradeで好きなrevisionにすることができますが、たいていは最新バージョンで更新すると思います。最新版にするにはheadと指定します。
PYTHONPATH=. alembic --config iniファイル upgrade head
#バージョンがおかしくなった時の修正
alembicはDBにalembic_versionというテーブルを作って、version_numにファイル名(最後の_は除く)を格納しているだけのシンプルなバージョン管理です。
なので、DBを最新版の形に合わせたのちversionsの中の最新のファイル名をversion_numに設定すれば、バージョンのズレはなくなります。
作業ディレクトリ下のversionsの中のスクリプトと、DBの中のalembic_versionテーブルを削除すれば、alembicによる設定はなかったことにできます。