タイトル: テーブル定義の確認
SEOタイトル: Django でテーブル定義を確認する方法完全ガイド
| この記事の要点 |
|
1. Migration が生成する SQL を見る
# 適用前のマイグレーション一覧
python manage.py showmigrations
# blog
# [X] 0001_initial
# [X] 0002_add_tags
# [ ] 0003_alter_post_slug ← 未適用
# 該当マイグレーションが生成する SQL
python manage.py sqlmigrate blog 0003
# 出力例(PostgreSQL)
# BEGIN;
# ALTER TABLE "blog_post" ALTER COLUMN "slug" TYPE varchar(200);
# COMMIT;
# すべての過去マイグレーション SQL
python manage.py sqlmigrate blog 0001
2. inspectdb: 既存 DB から Model 逆生成
# 既存 DB のスキーマを Django Model に変換
python manage.py inspectdb > legacy/models.py
# 特定テーブルだけ
python manage.py inspectdb users orders > legacy/models.py
# DB ルーター複数設定時
python manage.py inspectdb --database=legacy > legacy/models.py
出力例:
# legacy/models.py(自動生成)
class Users(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=100)
email = models.CharField(unique=True, max_length=255)
created_at = models.DateTimeField()
class Meta:
managed = False # ← Django で migration 管理しない
db_table = 'users' # ← 既存テーブル名
3. Model の内省(イントロスペクション)
from blog.models import Post
# テーブル名
print(Post._meta.db_table)
# blog_post
# 全フィールド
for f in Post._meta.get_fields():
print(f.name, type(f).__name__, getattr(f, 'max_length', None))
# 出力例:
# id BigAutoField None
# title CharField 200
# slug SlugField 200
# body TextField None
# created_at DateTimeField None
# author ForeignKey None
# tags ManyToManyField None
# 主キー名
print(Post._meta.pk.name) # id
# インデックス / 制約
print(Post._meta.indexes)
print(Post._meta.constraints)
# 外部キーで紐づくモデル
for f in Post._meta.get_fields():
if f.is_relation:
print(f.name, '→', f.related_model)
4. dbshell で生 SQL を見る
# settings の DATABASES に応じて自動接続
python manage.py dbshell
# PostgreSQL
\d blog_post
\d+ blog_post # 詳細
\dt # テーブル一覧
\di # インデックス一覧
# MySQL
SHOW CREATE TABLE blog_post\G
SHOW INDEX FROM blog_post;
SHOW COLUMNS FROM blog_post;
# SQLite
.schema blog_post
.tables
5. SQL ダンプ系コマンド
# 全アプリの「これから作る SQL」をまとめて
python manage.py sqlmigrate blog 0001 --backwards # 戻す SQL
# 全テーブルの空フラッシュ SQL
python manage.py sqlflush
# 全シーケンスをリセットする SQL(PostgreSQL)
python manage.py sqlsequencereset blog
# Django のシステムチェック
python manage.py check
python manage.py makemigrations --check --dry-run
6. django-debug-toolbar でリクエスト中の SQL
pip install django-debug-toolbar# settings.py
INSTALLED_APPS += ['debug_toolbar']
MIDDLEWARE += ['debug_toolbar.middleware.DebugToolbarMiddleware']
INTERNAL_IPS = ['127.0.0.1']
# urls.py
from django.urls import include, path
urlpatterns += [path('__debug__/', include('debug_toolbar.urls'))]
右側にパネルが表示され、ページ表示中のすべての SQL / 実行時間 / EXPLAIN が見られます。N+1 検出にも有効。
7. connection.queries(DEBUG=True 時のみ)
from django.db import connection, reset_queries
reset_queries()
# 何か処理
posts = list(Post.objects.select_related('author').all()[:10])
# 発行された全クエリ
for q in connection.queries:
print(q['time'], q['sql'])
# クエリ数
print(len(connection.queries))
8. GUI ツールで確認
| ツール | 対応 DB | 備考 |
|---|---|---|
| DBeaver | ほぼ全部 | 無料 / クロスプラットフォーム |
| TablePlus | 多数 | UI が綺麗 / 有償 |
| pgAdmin | PostgreSQL | 公式 |
| MySQL Workbench | MySQL | 公式 / ER 図出力 |
| DB Browser for SQLite | SQLite | 無料 |
9. ER 図を自動生成
pip install django-extensions pydotplus
# settings.py
# INSTALLED_APPS += ['django_extensions']
# 全モデルから ER 図 (graphviz)
python manage.py graph_models -a -o myapp_models.png
# 特定アプリのみ
python manage.py graph_models blog -o blog.png
# テキスト系
python manage.py show_urls # URL 一覧
python manage.py describe_form blog.PostForm
10. マイグレーションの差分を見る
# モデル変更後、まだ migration を作っていない差分
python manage.py makemigrations --dry-run --verbosity 3
# 作って即 SQL を確認
python manage.py makemigrations blog
python manage.py sqlmigrate blog 0004
# 適用前後の状態確認
python manage.py showmigrations
確認ワークフロー早見
| 知りたいこと | コマンド / 方法 |
|---|---|
| これから流れる SQL | sqlmigrate <app> <num> |
| 実 DB のテーブル定義 | dbshell → \d table / SHOW CREATE TABLE |
| 既存 DB を Model 化 | inspectdb |
| モデルのフィールド一覧 | Model._meta.get_fields() |
| リクエスト中の SQL | django-debug-toolbar / connection.queries |
| ER 図 | django-extensions graph_models |
FAQ
Q: sqlmigrate が「Migration is not migrated yet」エラー
A: 未適用マイグレーションも sqlmigrate は出力可能。Django のバージョン差。--no-color 付与 / 引数の順序確認。
Q: inspectdb で外部キーが取れない
A: SQLite の場合 foreign_keys プラグマを ON に。または DB エンジン側の FK 制約定義を確認(無いと検出不可)。
Q: テーブル名のプレフィックスを変えたい
A: class Meta: db_table = 'custom_name'。アプリ全体は settings.DATABASES['default']['OPTIONS'] では設定不可、モデル毎に。