ダークサイドにようこそ!

ブロググロブブログ

PostGIS(+PostgreSQL)環境でAlembicのマイグレーションする際の備忘録

PostGIS(+PostgreSQL)を使ってるPythonアプリの開発環境に、SQLAlchemy用のマイグレーションツールであるAlembicを導入したらいくつかハマったので備忘録です。

 

spatial_ref_sysテーブルの除外

PostgreSQL+PostGISでDBを作ると(自分はDocker Imageから作成)自動でspatial_ref_sysテーブルというのが作られるっぽいです(正確にはPostGISのエクステンション追加のタイミングかも)。PostGISが使用する空間参照系が定義されているらしい。sqlalchemyでそのモデル定義を書くことはなさそうだしAlembicに勝手にテーブル削除とかもされたくないので自動生成の対象から外した方が良い気がします。これはalembicのenv.pyにてテーブル名から除外することで対応できます(以下参照)。

stackoverflow.com

alembic.sqlalchemy.org

 

geoalchemy2が定義されてない

マイグレーション時にNameErrorが発生します(name 'geoalchemy2' is not defined)。これはversions以下に自動生成されたスクリプトに自分で都度import文を追記するか、script.py.mako(マイグレーション時に使われるテンプレート)にimport文を追記する必要がありました。1度の変更で済むので後者の方が楽そうです。以下を参考にさせていただきました。

stackoverflow.com

 

インデックスの重複(またハマったので追記)

マイグレーション時に「psycopg2.errors.DuplicateTable: relation "idx_hoge_polygon" already exists」的なエラーが発生します。同じ名前のインデックスをもう一度作ろうとしてエラーになっているようです。

モデルのカラムにGeometryを定義するとデフォルトでspatial_index=Trueとなり、geoalchemy2がSQLAlchemy のモデルメタデータにGIST インデックスの定義を登録します。Alembicはこのメタデータからマイグレーションファイルにop.create_index('idx_hoges_polygon', ...)と記述しますが、geoalchemy2はその前のテーブル作成時(op.create_table)にインデックスを自動で作っちゃうので、重複エラーとなってしまうようです。

対応としては、マイグレーションファイルで upgrade() 内の該当する create_index を削除、downgrade() 内の該当する drop_index を削除します(手動で)。原因のあたりはAIエージェントにも聞きながら書いたので、もし間違えあればご指摘ください。

geoalchemy-2.readthedocs.io

 

おまけ

あとPostGIS関係ないのですが、Dockerコンテナ上で「alembic upgrade head」実行する際にalembicが見つからないと言われハマってたのですが(インストールできてるのに)、これはalembic.iniがいる階層じゃないとコマンド実行できないというやつでした。下記URLみたいに「~.iniが見つからない」まで教えてくれてたらすぐ気づいたかも……勉強ですなあ。

stackoverflow.com

 

他にも何かあったかもなんですが、とりあえず今回は以上であります。追記しました。

 

 

hahaeatora.hateblo.jp

hahaeatora.hateblo.jp

hahaeatora.hateblo.jp