30秒でできる解決策
データベースは実質的に「要求された内容は理解しましたが、そのテーブルは記録にありません」と言っています。多くの場合、モデルの変更を実際のデータベーススキーマに反映(push)し忘れていることが原因です。以下の2つのコマンドを実行して同期させてください。
python manage.py makemigrations
python manage.py migrate
特定の機能を開発している場合は、ノイズを避けるためにそのアプリを直接ターゲットにします:
python manage.py makemigrations your_app_name
python manage.py migrate your_app_name
なぜこのエラーが発生するのか?
エラー 1146 は MySQL および MariaDB 特有のものです。Django の Object-Relational Mapper (ORM) が、現在のデータベースに存在しないテーブルに対してクエリを実行しようとしたときに発生します。これは単なる「テーブルの欠落」の問題ではなく、Python コードと SQL スキーマの間の同期ずれ(デシンクロナイゼーション)です。
よくある原因は以下の通りです:
- ゴースト・マイグレーション: 10個のフィールドを持つ新しい
Postモデルを作成したが、データベースがまだCREATE TABLEコマンドを受け取っていない。 - レジストリのギャップ:
INSTALLED_APPSリストに新しいアプリを追加し忘れている。Django がアプリを追跡していない場合、そのマイグレーションを探しません。 - 先走りしたコード: データベースの準備ができる前、Python がファイルをインポートした瞬間(例:
forms.py内など)に実行されるクエリを記述している。 - 手動による操作: 誰か(または別のスクリプト)が MySQL コンソールで直接テーブルを削除してしまい、Django の
django_migrationsテーブルとの整合性が取れなくなっている。
ステップバイステップの解決策
1. アプリの登録を確認する
Django は、明示的に登録されていないアプリのマイグレーションを無視します。settings.py を開き、アプリが存在するか確認してください。これは数時間のデバッグ作業を節約できる簡単なチェックです。
# settings.py
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
# ...
'blog_app', # ここでアプリ名が正確に記述されているか確認してください
]
2. 「鶏が先か卵が先か」のクエリ問題を解決する
よくある間違いは、ファイルのトップレベルでデータベースにクエリを実行することです。例えば、forms.py で直接すべてのカテゴリを取得してドロップダウンの選択肢を定義すると、Django はサーバーを起動した瞬間にその SQL を実行しようとします。
# これは行わないでください!インポート時に実行されます。
CATEGORIES = [(c.id, c.name) for c in Category.objects.all()]
class ProductForm(forms.Form):
category = forms.ChoiceField(choices=CATEGORIES)
もし category テーブルがまだ存在しない場合(最初のマイグレーション時など)、プロセス全体がクラッシュします。解決策: ModelChoiceField を使用してください。これは「遅延評価(lazy)」されるため、フォームが実際に使用されるまでデータベースにクエリを投げません。
class ProductForm(forms.Form):
# こちらの方が安全で、コードもすっきりします
category = forms.ModelChoiceField(queryset=Category.objects.all())
3. 同期がずれたマイグレーションからの復旧
データベース側ではマイグレーションが適用されたことになっているのに、テーブルが存在しないことがあります。あるいは、テーブルは存在するのに Django が再びそれを作成しようとすることもあります。このような場合に --fake フラグが非常に役立ちます。
テーブルはデータベースに存在するが、Django がそれを作成しようとし続ける場合は、SQL を実行せずにマイグレーションを「完了」として記録するよう Django に指示します:
python manage.py migrate your_app_name --fake
開発中に特定のアプリを最初からやり直したい場合は、そのアプリだけのマイグレーション履歴を消去できます:
- マイグレーション履歴のクリア:
python manage.py migrate --fake your_app_name zero - アプリの
migrations/フォルダ内にあるマイグレーションファイル(__init__.pyを除く)を削除する。 - 再生成と適用:
python manage.py makemigrationsを実行し、次にpython manage.py migrateを実行する。
4. データベースの直接確認
それでもエラーが表示される場合は、内部を確認しましょう。Django シェルを使用して、ORM がテーブルと通信できるかどうかを確認します。5秒で終わり、設定の問題を排除できます。
python manage.py shell
# シンプルなカウントクエリを試す
from your_app_name.models import YourModel
print(YourModel.objects.count())
これで数値(たとえ 0 であっても)が返ってくれば、テーブルは正常に存在しています。再び 1146 エラーが発生する場合は、SQL ターミナルに入り、SHOW TABLES; を実行してデータベースの内容を正確に確認してください。
プロのヒント:マルチデータベース環境
メインとサブのデータベースを使用していますか?Django が間違ったデータベースを参照している可能性があります。テーブルがサブのデータベースにある場合は、マイグレーションコマンドでそれを指定する必要があります:
python manage.py migrate --database=external_db

