備忘録:SQLAlchemyのORMとCoreを組み合わせて使うのが良さそう

最近、身をもって学んだことの備忘録。SQLの薄いラッパーとしてSQLAlchemyを使いたいプロジェクト(後述)では以下の方針で進めるのが良いと思う。

  • ORMレイヤーで、クラス定義をする
  • Coreレイヤーで、クエリー生成をする
    • ただしテーブルオブジェクトではなくクラスを使ってクエリーを組み立てる

あと余談だけれど: MetaData.create_allは手軽に始められるものの「必ず」に近いレベルで最初からalembicを使うべき。その理由の一つとしては、create_allを使うと制約名などが自動生成され、後付けでマイグレーションスクリプトを書くときにそれらの命名規則を調査する等の不毛な苦労を強いられることが挙げられる。

「SQLの薄いラッパーとしてSQLAlchemyを使いたいプロジェクト」について。データ分析や機械学習がトピックとなるシステムで大量データを扱う複雑なクエリーを「開発」するとき、ORMのプログラミングで試行錯誤するとPythonコードとSQLの相互変換で思考負荷がかかってしまい効率が悪い(考えにくい)。そのため各DBMSのコマンドインタフェースやDBeaverのようなSQLのREPL環境でSQL言語を使って試行錯誤するのが一番効率的だと考えている。するとデバッグ時にはSQLと Pythonコードを行き来することになるので、翻訳の落差が大きいORM的なプログラミングスタイルよりも、SQLを素直にPython言語に翻訳したようなプログラミングスタイルで書きたくなる。それはSQLAlchemyで言うとCoreレイヤーになるわけだけれど、Coreレイヤーでのプログラミングでは(公式ドキュメントの構成の影響もあって)テーブルスキーマを直接表現したTableオブジェクトをクエリー構築に使いがちだった。しかし実際にはORMのクラスのフィールドでもクエリー構築に使えるので、そうすると最近Python界で充実してきな静的型チェックなとが機能するようになり、開発効率と品質の両方に貢献してくれる。