django-mptt から django-tree-queries への移行

概要 django-mptt は README で「This project is currently unmaintained」と宣言している。後継として推奨される django-tree-queries は同じメンテナ(Matthias Kestenholz)の手による Recursive CTE 実装で、書き込みコストが O(N) から O(1) に改善される。 なぜ unmaintained になったのか MPTT(Modified Preorder Tree Traversal)はノード挿入・移動のたびに全ノードの lft/rght を更新する必要があり書き込みが O(N) 並行書き込みに弱く、TreeManager.rebuild() が「壊れることを前提とした API」であることを物語る PostgreSQL 8.4(2009)以降、すべての主要 DB が WITH RECURSIVE をサポートしており、MPTT の存在意義が薄れた メンテナは「放棄」ではなく「アルゴリズム的な世代交代を促している」 django-tree-queries のアプローチ parent 列 1 本だけを持ち、深さや祖先パスをクエリ時に Recursive CTE で動的に計算する。 書き込み: parent_id を更新するだけ → O(1) 読み取り: CTE 1 発で深さ・祖先・並び順を取得 並行性: ツリー操作で他行が壊れない リビルド不要: 冗長データが存在しない 移行手順 1. 整合性確保(移行前) 1 python manage.py shell -c "from myapp.models import Category; Category.objects.rebuild()" 2. モデル定義の差し替え 1 2 3 4 5 6 7 8 9 10 # Before: django-mptt from mptt.models import MPTTModel, TreeForeignKey class Category(MPTTModel): parent = TreeForeignKey('self', null=True, blank=True, on_delete=models.CASCADE) # After: django-tree-queries from tree_queries.models import TreeNode class Category(TreeNode): name = models.CharField(max_length=100) # parent は TreeNode が定義済みなので不要 3. マイグレーション生成 1 2 python manage.py makemigrations # lft / rght / tree_id / level の DROP マイグレーションが自動生成される 4. API 対応表 django-mptt django-tree-queries node.get_descendants() Category.objects.descendants(node) node.get_ancestors() Category.objects.ancestors(node) node.get_children() node.children.all() node.is_leaf_node() not node.children.exists() node.level node.tree_depth(with_tree_fields() 必要) Model.objects.all() Model.objects.with_tree_fields() Model.objects.rebuild() 不要(存在しない) 5. テンプレートタグの置換 1 2 3 4 5 6 7 8 9 10 11 12 13 14 {# Before: django-mptt #} {% load mptt_tags %} {% recursetree categories %} <li>{{ node.name }}</li> {% endrecursetree %} {# After: django-tree-queries #} {% load tree_queries %} {% tree_info categories as tree %} {% for node, structure in tree %} {% if structure.new_level %}<ul>{% endif %} <li>{{ node.name }} {% for level in structure.closed_levels %}</li></ul>{% endfor %} {% endfor %} 落とし穴 Ordered insertion が無い — MPTTMeta.order_insertion_by 相当は存在しない。必要なら position 列を自前で導入 管理画面の UI — DraggableMPTTAdmin は付属しない。必要なら別ライブラリか自作 大規模 CTE のコスト — 数十万ノードの descendants クエリは MPTT の BETWEEN lft AND rght より遅い場合がある。本番データで EXPLAIN を取ること MySQL 5.7 以下は非対応 — Recursive CTE は MySQL 8.0+ が必要 DRF シリアライザの書き直し — MPTT 専用 TreeSerializer を使っていると変更が必要 移行コストの目安 項目 コスト スキーマ移行 数分(makemigrations + migrate) モデル定義変更 数分〜数十分 API 呼び出しの全置換 数日〜数週間(規模次第) テンプレート/Admin 改修 数日 判断基準 ケース 推奨 既存案件で安定稼働中、ツリー編集が稀 django-mptt のまま 新規プロジェクト、PostgreSQL/MySQL 8+ 最初から django-tree-queries MySQL 5.7 以下が必須 django-mptt または django-treebeard 関連ページ FastAPI — Django と同様の Python Web フレームワーク DRF(Django REST Framework) — API 移行時に関連するシリアライザ ソース記事 django-mptt はなぜ「unmaintained」と書かれているのか — そして django-tree-queries への移行 — 2026-04-20

2026年4月27日 · 2 分

django-mptt はなぜ「unmaintained」と書かれているのか — そして django-tree-queries への移行

django-mptt の README を開くと、いきなり以下の文言が目に飛び込んでくる。 This project is currently unmaintained You can find alternatives to django-mptt on Django Packages. Maybe you do not need MPTT, especially when using newer databases. See django-tree-queries for an implementation using recursive Common Table Expressions (CTE). 「単に飽きて投げ出した」のか、それとも「技術的に役目を終えた」のか。本稿では django-mptt のリポジトリ、CHANGELOG、ソースコードを実際に読んで、その背景と後継への移行可否を整理する。 1. 経緯 — メンテナンス側の事情 CHANGELOG.rst を時系列で追うと、放棄宣言とその後の経緯が見て取れる。 v0.13: 公式に「unmaintained」を宣言 0.13 ==== - **MARKED THE PROJECT AS UNMAINTAINED, WHICH IT STILL IS** - Reformatted everything using black, isort etc. - Switched from Travis CI to GitHub actions. ... この時点で「もうメンテしません」と公式宣言がなされた。 ...

2026年4月20日 · 5 分

Amazon S3 Files GA:消えるアーキテクチャ層と生まれるアーキテクチャ

2026年4月7日、AWSがAmazon S3 Filesを一般提供(GA)しました。S3バケットをNFS v4.1/v4.2のファイルシステムとしてマウントできる機能で、EC2・EKS・ECS・Lambdaのいずれからでも利用できます。 本記事は、ikenyal氏のZenn記事「S3 Filesで消えるアーキテクチャ層、生まれるアーキテクチャ」を参照しながら、S3 Filesが既存のアーキテクチャにどう影響するかを整理します。「何が設定できるか」ではなく「何が不要になり、何が可能になるか」にフォーカスします。 S3 Filesが解こうとしている問題 たとえば、MLチームが学習データの前処理をする場面を考えましょう。元データはS3に置いてあり、pandasで読み込んで加工したい場面です。 pd.read_csv("s3://my-bucket/data.csv") と書けますが、内部ではboto3がGETリクエストを発行してメモリに読み込んでいます。手元の open("./data.csv") とは根本的に異なるI/Oモデルです。 規模が大きくなると、これは「パイプラインのアーキテクチャ課題」になります。 S3からEFS/EBSにコピー → 処理 → 結果をS3に書き戻す この「中間のコピー層」は本来やりたい処理ではなく、ストレージのI/Oモデルの違いを埋めるためだけに存在しています。 S3 Filesはこのギャップそのものを解消します。アプリケーションからS3のデータはローカルのディレクトリに見えます。 1 2 3 # S3 Filesを使うと pd.read_csv("/mnt/s3files/data.csv") # S3のオブジェクトが読まれる df.to_csv("/mnt/s3files/result.csv") # 変更が自動的にS3にコミットされる FUSEベースのツールとの違い 「S3をマウントできる」と聞いて、Mountpoint for Amazon S3やgcsfuseを思い浮かべる方も多いでしょう。S3 Filesは内部構造がまったく異なります。 FUSEベースのツールは、S3 APIの上にファイルシステムの振る舞いを「エミュレーション」するアプローチです。ファイルの一部だけを書き換えるような操作がサポートされず、空ディレクトリの扱いに不整合が出ることもあります。 S3 Filesはエミュレーションではなく、EFS(Elastic File System)という本物のNFSファイルシステムをS3に接続しています。二つの異なるシステムが共存し、その間に明示的な同期レイヤーがある構造です。 「stage and commit」モデル ファイルシステム上での変更は即座にS3に反映されるのではなく、約60秒ごとにまとめてS3へPUTされます(「commit」)。逆に、S3側でオブジェクトが更新された場合は通常数十秒以内にファイルシステム側に反映されます。 これは明確なトレードオフです。「リアルタイムに同期される共有ファイルシステム」ではなく、「数十秒の遅延を許容する代わりに、ファイルとオブジェクトの両方のセマンティクスを壊さない」設計です。 消えるアーキテクチャ層 1. S3 → EFS/EBSのステージングパイプライン 100GBの学習データを処理する場合、従来の手順は: S3からEBSにダウンロード(数分かかる) データを処理する 結果をS3にアップロード EBSボリュームをクリーンアップ やりたい処理は2番だけです。S3 Filesでは、S3プレフィックスをマウントするだけで処理スクリプトはそのまま /mnt/s3files/ のファイルを読み書きします。ダウンロード・アップロード・クリーンアップのステップが消えます。 ...

2026年4月9日 · 4 分

Celery

概要 Redis や RabbitMQ をブローカーに、非同期タスク実行・定期タスク(beat)を実現。ECS Fargate 上では worker/beat を独立タスクとして実行。ログは CloudWatch Logs に出力。 関連ページ Redis — Celery のブローカー/バックエンド ソース記事 Celery — 2023-04 Celery on ECS — 2023-07

2026年4月6日 · 1 分

CloudFront → ALB → Django の HTTPS 判定

概要 CloudFront + ALB + Django 構成では ALB が X-Forwarded-Proto を上書きするため、Django に HTTP 判定されて API レスポンス URL が http:// になる問題。CloudFront の custom_header(X-Forwarded-Ssl)は ALB に干渉されない。Django の SECURE_PROXY_SSL_HEADER をカスタムヘッダー参照に変更。

2026年4月6日 · 1 分

Django REST Framework (DRF)

概要 ModelSerializer で ORM↔API マッピング自動化。ViewSet で CRUD 一括定義。Content Negotiation、Pagination、Filtering、Permission クラスで機能実装。 関連ページ FastAPI — Python の別の API フレームワーク ソース記事 DRF — 2023-05

2026年4月6日 · 1 分

Redis

概要 インメモリストレージで、Memcached より豊富なデータ構造(List・Set・Sorted Set・Stream)対応。Django キャッシング・Celery ブローカー・セッションストアとして広く活用。ElastiCache クラスターモードでシャーディング・高可用性確保。 分散ロック Lua スクリプトによる複数コマンドのアトミック実行で競合状態を回避。フェンシングトークンで堅牢なロック実装が可能。 関連ページ 分散ロック — Redis を使った排他制御 Celery — Redis をブローカーとして利用 ソース記事 Redis — 2023-05 Redis フェンシングロック — 2026-03

2026年4月6日 · 1 分

分散ロック

概要 Redis-py の Lock クラスは UUID ベースのトークン管理を提供。フェンシングトークン(単調増加する数値)を実装することで、GC pause による False Positive を防止する堅牢な分散ロックが実現可能。Lua スクリプトでアトミック性を保証。 関連ページ Redis — 分散ロックの基盤 ソース記事 Redis フェンシングロック — 2026-03 Django Cache Lock — 2024-01

2026年4月6日 · 1 分

Claude Code で Laravel→Django 全自動移行をやってみた(1/3)計画編

業務管理システム(PHP/Laravel 6.20)を Python/Django 4.2 に移行するプロジェクトを、Claude Code の自律実行でほぼ全自動で完遂しました。 移行元: Laravel 6.20 / PHP 8.0 / MySQL 5.7 / Blade テンプレート 移行先: Django 4.2 LTS / Python 3.11+ / MySQL 8.0 / Django Templates 所要時間: 約 5.5 時間(準備フェーズ除く) 成果物: 17 モデル / 50+ テンプレート / 199 テスト / 15,000 行の Python コード 本記事は 3 部構成です。 計画編(本記事)— なぜやったか、どう計画したか 自動化基盤編 — Claude Code を自律実行させるフレームワークの設計 実行結果・教訓編 — 実際に何が起きたか、次回への教訓 プロジェクトの背景 移行対象は、ある業種特化の業務管理システムです。契約管理・マスタ管理・CSV インポート・Excel エクスポート・月次締処理・外部サービス連携(OAuth2 / REST / GraphQL)など、典型的な業務アプリの機能を一通り備えています。 ...

2026年3月26日 · 3 分

Claude Code で Laravel→Django 全自動移行をやってみた(2/3)自動化基盤編

前回の計画編では、移行の方針とフェーズ設計を紹介しました。本記事では、計画を実際に自律実行するためのフレームワーク設計を解説します。 全体アーキテクチャ 自律移行の仕組みは、大きく 3 つのレイヤーで構成されています。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 ┌─────────────────────────────────────────────────────┐ │ オーケストレーション層: run-issue.sh │ │ - Issue 読み込み → ブランチ作成 → Claude 起動 │ │ - リトライ → Push → PR 作成 → マージ → Issue 閉じ │ └──────────────────┬──────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────┐ │ 実行層: Claude Code (claude -p) │ │ - ソースコード調査 → 設計 → 実装 → テスト │ │ - コミット(push はしない) │ │ - サブエージェント: explorer / architect / reviewer│ └──────────────────┬──────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────┐ │ 品質保証層: Hooks + CI + verify-phase.sh │ │ - Pre-commit: ruff format + check │ │ - PostToolUse: 編集時の即座リント │ │ - CI: lint → Django check → pytest │ │ - Phase 検証: ファイル存在 + 機能チェック │ └─────────────────────────────────────────────────────┘ 責務分離の原則 最も重要な設計原則は、ワークフロー制御と実装作業の責務分離です。 ...

2026年3月26日 · 5 分