🙂

alembicをrailsと比較しながら使ってみた

2024/05/03に公開

はじめに

LangChainとDBの連携のサンプルコードを書いてる中で、唐突に出てくるテーブルの構造も一緒に置いておかないと、後で見たときにわからなくなるなと思い、alembicを触ってみることに

環境の分け方が色々ある

ここで言う環境というのは、developmentとかproductionのことになりますが、
venvなどを実行した後、alembic initを実行すると↓のようなiniファイルができます。
https://alembic.sqlalchemy.org/en/latest/tutorial.html#editing-the-ini-file
iniファイルか、、、と思ったんですが、変数は埋め込めるようです。

また、
https://alembic.sqlalchemy.org/en/latest/cookbook.html#run-multiple-alembic-environments-from-one-ini-file
こういう方法もあるようですが、結局最終的にはDBのパスワードなどは、AWS Secrets Managerなどに保管すると思うので、環境変数を埋め込みたいです。

そういえば、FastAPIってどうしているのかと、思って調べるとこんなファイルを見つけました。
https://github.com/tiangolo/full-stack-fastapi-template/blob/master/backend/alembic.ini

https://github.com/tiangolo/full-stack-fastapi-template/blob/master/backend/app/alembic/env.py

alembic.iniのsqlalchemy.urlの部分がないですね。代わりにenv.pyで設定しています。潔い感じがします。とりあえず、これを採用することに。

create databaseはやってくれないらしい

alembic revision -m "create products table"のような感じで、
rails g migration的なことを行いproductsテーブルの定義を追加してみました↓
https://github.com/na8esin/LangChain-sample/blob/fa0d8d0468436bb39bf1bc503a55c67861de4d86/alembic/versions/dfebef2f0749_create_product_table.py

railsと違って、rollback(alembicだとdowngrade)する場合のdrop_tableは書かないといけないみたいです。

その後、alembic upgrade headを実行すると

sqlalchemy.exc.OperationalError: (MySQLdb.OperationalError) (1049, "Unknown database 'alembic_practice'")
(Background on this error at: https://sqlalche.me/e/20/e3q8)

となります。

下記を見るとやっぱりcreate databaseやってくれないみたいです。
https://github.com/sqlalchemy/alembic/issues/614

mysqlだとcollationとかcharsetとか気になるので、どこかにcreate文を置いておきたいですが、ちょっといい方法が見当たらなかったです。

docker環境なら、docker-compose.ymlに
https://github.com/na8esin/LangChain-sample/blob/9c2adbad9921e43bc0341e962c36e1be9ebfac42/docker-compose.yml
のような感じで設定しておくので、予想がつきそうではありますが。

気を取り直して手動でDBを作成して、

alembic upgrade headを実行します。

そうすると、

CREATE TABLE `products` (
  `id` int NOT NULL AUTO_INCREMENT,
  `name` varchar(50) COLLATE utf8mb4_bin NOT NULL,
  `description` varchar(200) COLLATE utf8mb4_bin DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin

こんな感じで出来上がりました。

同時に、alembic_versionテーブルも下記のように作られます。

ただ、railsのschema.rbのようなものはデフォルトでは出力されないので、
alembic upgrade head --sql > migration.sql
を実行するか、下記を参考にしてカスタマイズしていくようです。
https://alembic.sqlalchemy.org/en/latest/offline.html#customizing-the-environment

終わりに

内容的には大したことがなかったですが、新しいライブラリを使うときには、最初は苦労が多いなと改めて思いました。

しくみのテックブログ

Discussion