「25年以上ORMを使い続けてきたが、生クエリとdataclassesに切り替えた」
Redditのr/Pythonで、こんな投稿が話題になりました。
投稿者はPythonコミュニティで知名度のある開発者です。
しかも、ORM推進派を自認していた人物でした。
その人が方針転換した理由が興味深い。
AIアシスタントとの協働体験がきっかけだったのです。
本記事では、この投稿とコミュニティの反応を紹介しながら、ORMと生クエリの選択について考察します。
方針転換の理由:AIは生クエリのほうが得意
投稿者の主張はシンプルでした。
AIコーディングアシスタント(具体的にはClaude)と本格的に開発してみた。
すると、AIはORM固有のコードよりネイティブなクエリ構文のほうが圧倒的に上手く書けると気づいた、と。
根拠として挙げられていたのが、ダウンロード数の差です。
たとえばPyMongoは、Beanie(MongoDB向けODM)の53倍のダウンロード数を誇ります。
しかも、MongoDBのネイティブクエリ構文はNode.jsやPHPなど多くのエコシステムで共通です。
つまり、AIの学習データにおける情報量の差は歴然なのです。
AIアシスタントに書かせるなら、マイナーなORM固有の書き方より、広く使われている標準的なクエリ構文のほうが品質は高くなる。
この発想自体は筋が通っています。
「Raw+DC」パターンとは何か
投稿者が提唱するのは「Raw+DC」パターンと呼ばれるアプローチです。
データベースには生クエリでアクセスします。
そして、データアクセス層の境界でPythonのdataclassesに変換する。
変換層はfrom_doc()のような関数で、辞書をdataclassに写すだけです。
型安全性やIDEの自動補完、型チェッカーのサポートは維持されます。
一方で、ORM依存のリスクからは解放される。
実際、MongoEngineはすでに開発停止しています。
Beanieも開発の勢いが落ちているとの指摘がありました。
投稿者いわく、この変換ボイラープレートこそAIが得意な領域だと。
生成も保守も任せやすい種類のコードだからです。
コミュニティの反応:「それ、ORM作り始めてるだけでは?」
最も高評価を集めたコメントは痛快でした。
「おめでとう。自作ORMの開発を始めたね。」
多くの支持を獲得したこの一言に、投稿者も「ありがとう。どこまで行くか見てみよう」と余裕を見せていました。
この指摘には背景があります。
多くの開発者が同じ道を歩んできたからです。
既存のORMに不満を覚え、シンプルなデータアクセス層を自作する。
最初は数十行で済んでいたコードが、気づけば肥大化する。
そして最終的には、フル機能のORMとほぼ同じものが出来上がる。
ベテラン開発者ほど、この「あるある」に共感したわけです。
ただし反論もありました。
ある開発者の主張はこうです。
ORMの核心はクエリを自動生成する部分であって、行をオブジェクトにマッピングする部分ではない。 投稿者のコードはSQLを一切生成していないのだから、ORMとは呼べない
この定義をめぐる議論はかなり白熱しました。
Wikipediaの記述まで持ち出されていたほどです。
型安全性をめぐる疑問
もう一つ大きな論点になったのが、dataclassesの型安全性についてです。
「dataclassesはどういう意味で型安全なのか?」という率直な質問が投げかけられました。
これに対し、複数の開発者が指摘したのは次の事実です。
標準ライブラリのdataclassesは、引数の数さえ合えば間違った型でもインスタンスを生成してしまう。
@dataclass
class Data:
field_1: int
a = Data("one") # エラーにならない
投稿者は、エディタの警告やmypy/pyrightでの静的チェックを型安全性の根拠として挙げました。
しかし、「25年の経験でそれか」という厳しい声も上がっていました。
実行時の型チェックが必要なら、Pydanticのようなライブラリが適している。
これがコミュニティの多数意見です。
Pydantic vs cattrs vs msgspec:変換層の選択肢
dataclassesの代替として、複数のライブラリが議論に上がりました。
まず、cattrsの作者自身がスレッドに登場しています。
共有された情報は興味深いものでした。
cattrsはクラスを一度だけ検査し、execで変換関数をコンパイルする。
そのため、手書きの変換コードより速くなる場合がある。
さらに、エッジケースのバリデーションも行ってくれるとのことです。
Pydanticについては評価が分かれました。
API入力のバリデーションには優れている。
しかし、v2で複雑さが増したという声が目立ちます。
ある開発者は、v2.0、2.1、2.2が互いに非互換だった経験を共有していました。
カスタム型のバリデーションで「アノテーション地獄」に陥りやすい点も指摘されています。
また、構造化とシリアライゼーションを混同している設計への不満も挙がっていました。
msgspecは、より軽量で高速な選択肢として評価されていました。
cattrsやattrsと合わせて、Pydanticの代替として推す声は少なくありません。
用途に応じた使い分けが妥当でしょう。
APIレベルのバリデーションにはPydantic。
大量データのパイプライン処理にはcattrsやmsgspec。
万能な正解は存在しません。
SQLAlchemyとの共存という現実解
「軽く使えばいいのでは?」という声も多く見られました。
SQLAlchemyのクエリヘルパーをほぼ直接使いつつ、ORMの恩恵も受けるという折衷案です。
ある開発者は、50行の生SQLを10行のPythonに変換できた経験を共有しています。
一方で、SQLAlchemyのパフォーマンスへの懸念も上がっていました。
psycopgを直接使う場合と比べて、テストスイートの実行時間が倍になったという報告があります。
また、大量の一括挿入やアップサートではメモリ使用量が膨れ上がる。
そのため、低レベルのエスケープハッチを使うべきだという指摘もありました。
結局のところ、シンプルなCRUD操作ではORMでもraw SQLでも大差はない。
複雑なクエリではraw SQLのほうが書きやすい。
ただし、保守性ではORMに軍配が上がる。
これが多数派の見方でした。
セキュリティ面の懸念
「AIエージェントが仕込んだSQLインジェクションでDBが吹き飛ぶ様子を想像してごらん」
このコメントは冗談半分です。
しかし、重要な指摘を含んでいます。
投稿者のブログ記事には、SQLインジェクション対策についての十分な分析がありませんでした。
ORMが暗黙的に提供してくれるセキュリティ機能を、生クエリに移行する際にどう担保するか。
この点は見落とされがちです。
投稿者は「コードを書くのがAIでも、レビューするのは人間だ」と返答しました。
しかし、「それは楽観的すぎる」と突っ込まれていたのも事実です。
AI時代のデータアクセス層を考える
この議論全体を通じて見えてくるのは、AIとの協働がソフトウェア設計の判断基準を変えつつあるという現実です。
従来の「開発者にとっての抽象化」と「AIにとっての扱いやすさ」が対立する場面が出てきました。
ORMは人間の開発者に有効な抽象化を提供してきた。
しかし、AIアシスタントにとっては、学習データの豊富な標準的クエリ構文のほうが扱いやすいのです。
とはいえ、ある開発者が鋭く問いかけていました。
「もし同僚が(AIではなく)手書きで全クエリを書いたとしても、同じ判断をするか?」と。
コードを誰が書いたかで設計判断を変えるべきなのか。
これは簡単に答えの出ない問いです。
まとめ
ORMか生クエリかという議論は、何十年も続いてきたテーマです。
しかし、AIアシスタントの登場で新しい切り口が加わりました。
Raw+DCパターンはシンプルで分かりやすく、AI時代の一つの選択肢として検討に値します。
ただし、考慮すべき点もあります。
型安全性の限界、セキュリティ対策の自己責任、そして「結局自作ORMを作り始める」リスク。
これらを含めて判断する必要があるでしょう。
Redditのコメント欄が示しているのは、銀の弾丸は存在しないという古くからの教訓です。
プロジェクトの規模、チームのスキルセット、AIとの協働度合い。
これらに応じて適切なアプローチを選ぶ。
当たり前の結論ですが、それが最も実践的な答えなのだと改めて感じさせられる議論でした。
