3.

Django でテーブル定義を確認する方法完全ガイド

編集
この記事の要点
  • Migration が生成する SQL: python manage.py sqlmigrate
  • 逆生成: python manage.py inspectdb(既存 DB → Django Model)
  • モデル内省: Model._meta.get_fields(), Model._meta.db_table
  • 実 DB の DDL: psql \d table, MySQL SHOW CREATE TABLE, SQLite .schema
  • リクエスト中のクエリ可視化: django-debug-toolbar / connection.queries

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 が綺麗 / 有償
pgAdminPostgreSQL公式
MySQL WorkbenchMySQL公式 / ER 図出力
DB Browser for SQLiteSQLite無料

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

確認ワークフロー早見

知りたいことコマンド / 方法
これから流れる SQLsqlmigrate
実 DB のテーブル定義dbshell\d table / SHOW CREATE TABLE
既存 DB を Model 化inspectdb
モデルのフィールド一覧Model._meta.get_fields()
リクエスト中の SQLdjango-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'] では設定不可、モデル毎に。

編集
Post Share
子ページ

子ページはありません

同階層のページ
  1. Model の定義方法
  2. マイグレーションファイルの作成
  3. テーブル定義の確認
  4. テーブルの作成
  5. テーブル名 = アプリケーション名 + モデル名の設定変更
  6. モデルの中身を確認