LoginSignup
0
0

【Django】既存のmodelに外部キーを追加し、再度migrationする

Last updated at Posted at 2022-05-19

はじめに

既存のModelに外部キー(Foreign Key)を追加しmigrationしてDBに反映させる手順と、起きやすいエラー・その対処法についてご紹介します。

1. 既存のModelに外部キーを追加

Studentモデルに外部キーを追加し、test appのClassモデルと紐付けて、生徒をクラス単位で管理できるようにする想定で書いていきます。

models.py
from django.db import models
from test.models import Class

class Student(models.Model):
     # Foreign Key追加
     class_id = models.ForeignKey(Class, models.DO_NOTHING)

2. Makemigrationsする

$ python manage.py makemigrations

このとき、次のような質問が表示されることがあります。

You are trying to add a non-nullable field 'class_id' to student without a default; we can't do that (the database needs something to populate existing rows).
Please select a fix:
 1) Provide a one-off default now (will be set on all existing rows with a null value for this column)
 2) Quit, and let me add a default in models.py

これは、「class_idフィールドには何らかの値を入れる必要があるよ〜」という意味です。
この場合、次の2つの対処方法があります。

1つ目は、フィールドにdefault=1を追加する方法です。追加したら、再度makemigrationsをします。

models.py
class Student(models.Model):
     class_id = models.ForeignKey(Class, models.DO_NOTHING, default=1) 

2つ目は、上記の質問が表示された時に「1」を選択し、デフォルト値として「1」を入力する方法があります。

Select an option: 1
Please enter the default value now, as valid Python
The datetime and django.utils.timezone modules are available, so you can do e.g. timezone.now
Type 'exit' to exit this prompt
>>> 1
Migrations for 'student':
  student\migrations\0010_student_class.py
    - Add field class_id to student

3. migrateする

migrateしてDBに変更を反映します。

$ python manage.py migrate

ここで、紐付け先のテーブル(この記事ではClassテーブル)に先ほど設定した id=1 のデータが無いと、次のようなエラーが出ます。

psycopg2.errors.ForeignKeyViolation: テーブル"student_student"への挿入、更新は外部キー制約"student_student_class_id_dbc8139b_fk_class_id"に違反しています
DETAIL:  テーブル"class"にキー(class_id)=(1)がありません

この場合は直接テーブルに、idカラムに1のデータを追加してあげるとmigrateが通ります。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0