DJANGO (+DRF) ER図およびテーブル定義の自動作成
数年ぶりに以前作成したDJANGO DRFのAPIサーバーのデータベース(POSTGRESQL)の資料(データベースの関連がわかる資料)を作成しようと思い、最初はmodels.pyをLLMに読ませてみたところうまくいかず、DUMPのsqlファイルからdot作成してなんて試してもうまくいかずでした。
もともとCRUDなど気にせずFLASKで自由気ままに作っていた野良WEB開発者でしたのでDJANGOを使わなければいけないときは結構苦痛でした。すべてPROJECTの設定ファイルであるsettings.pyの設定であったり、フォルダー構造ががっちりきまっていたりとか、すべて python manage.py xxxx しないといけないみたいな。カスタムSQLをBATCHで動かすのも
[プロジェクトフォルダー]/[アプリフォルダー]/management/commands なんてしなかったり行けなかったり、認証となるとデフォルトで入っている認証とWEBページでなくAPIサーバーとして出すときに非常にとっつきにくい印象はありましたし、面倒だなと思ってました。書籍もほとんどがいわゆるWEBページでDRFはあまりなく、手探りで進めてですが。
ちなみに、以下の書籍は数少ないというか私が知る限りただ1つのDJANGO DRFを日本語で開設した書籍でした。(私は筆者とは面識もメッセージのやり取りも一切なしの無関係な人間です。一応。本当に役に立ったということで引用してます)
現場で使える Django REST Framework の教科書[3.2 LTS 対応版] (Django の教科書シリーズ) [Print Replica] Kindle Edition
by 横瀬 明仁 (Author)
まあ、使っているうちに慣れればこんなもんかと面倒くささがなくなり、開発終盤では逆に、お作法さえ覚えれば、APIのドキュメントを自動作成してSWAGGERで公開などとメリットも多いと感じになりました。(機会があったらこの記事も書きます!)
さて本題でPOSTGRESでできたER図を何とか出せないかと思っていたところ、やっぱりありました!自動で作ってくれる方法!!!
django-extensions + graphviz DJANGOのER図自動作成(Ubuntu 24.04)
方法かいたって簡単でした。
- django-extensions をインストール
pip install django-extensions
- graphviz をインストール
apt install graphviz
- 一応図を編集アプリで変更できるようにdotのパッケージもいれます
pip install pydot
- プロジェクトのsettings.pyに以下をついかです
INSTALLED_APPS = [
...
'django_extensions',
]
- 図作成
python manage.py graph_models -a -o er_diagram.png
あっけなくかなりプロフェッショナルな見栄えのものできました。
テーブル定義のEXPORT
全体を俯瞰するのであればER図でいいかもしれませんが、やはり個別のテーブルを確認したり、ましてやDJANGOでシステム作って現在のデータを最初に一括でデータインポートが必要になるとどうしてもER図だけでなく詳細なリストが必要です。以下の手順で簡単にできました。プロジェクト内の各models.pyを自動で読んで、テーブル定義にするためのPYTHONスクリプトです。
[table_definition.py]
import csv
from django.apps import apps
output_file = "table_structure.csv"
# すべてのアプリのモデルを取得
models = apps.get_models()
# CSV に保存
with open(output_file, mode="w", newline="", encoding="utf-8") as file:
writer = csv.writer(file)
# CSV ヘッダー
writer.writerow([
"Table Name", "Table Verbose Name", "Column Name", "Column Verbose Name",
"Data Type", "Nullable", "Unique", "Default", "Max Length", "Foreign Key To"
])
for model in models:
table_name = model._meta.db_table # テーブル名
table_verbose_name = getattr(model._meta, "verbose_name", table_name) # テーブルの人間向けの名前(未設定ならテーブル名)
for field in model._meta.fields:
column_name = field.name # カラム名
column_verbose_name = getattr(field, "verbose_name", column_name) # カラムの人間向けの名前(未設定ならカラム名)
data_type = field.get_internal_type() # フィールドの型
nullable = field.null # NULL 許可(True or False)
unique = field.unique # ユニーク制約(True or False)
default = field.default if field.default is not None and field.default != field.empty_strings_allowed else "None"
max_length = field.max_length if hasattr(field, "max_length") else "N/A" # 最大長(文字列型のみ)
# 外部キーの関連先テーブルを取得
foreign_key_to = "N/A"
if data_type == "ForeignKey":
foreign_key_to = field.related_model._meta.db_table # 関連先テーブル名を取得
# CSV に書き込み
writer.writerow([
table_name, table_verbose_name, column_name, column_verbose_name,
data_type, nullable, unique, default, max_length, foreign_key_to
])
print(f"テーブル構造を {output_file} に出力しました。")
このスクリプトをDJANGOのルートに設定して以下を実行します。
python manage.py shell
pythonが立ち上がりますので以下で定義がエクスポートされます.
models.pyにしっかりとverboseでカラムの意味を記述しておけばちゃんとして定義書になります。
exec(open("table_definition.py").read())
Discussion