0
0

More than 1 year has passed since last update.

【Django】既にデータが入っている既存テーブルにユニークキーを追加したい時

Posted at

単純にやろうとするとどうしてもエラーがでてしまいますよね。
そんなときに使える処方箋です。

class Profile(models.Model):
    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    ## user_nameを追加
    user_name = models.CharField(max_length=40, null=False, blank=False, unique=True)
    display_name = models.CharField(max_length=40, blank=True)

既存のテーブルに上記の unique=True がついた、 user_name カラムを追加しました。

この状態で, python manage.py migrate するとエラーで怒られると思います。

マイグレーションファイルをいじります。

python manage.py makemigrations を叩いて作成されたマイグレーションファイルを編集します。

from django.db import migrations, models

## 以下のメソッドを追加
def set_default_code(apps, schema_editor):
    """
    既存の行に対してuser_nameを一意の名前で追加する関数
    """

    profile_model = apps.get_model('app_name', 'Profile')
    for row in profile_model.objects.all():
        row.user_name = 'UserName_{}'.format(row.display_name)
        row.save()


class Migration(migrations.Migration):

    dependencies = [
        ('app_name', '0007_profile_image'),
    ]

    operations = [
        migrations.AddField(
            model_name='profile',
            name='user_name',
            ## 作成された直後はここにunique=Trueが書いてあると思うけどそれは削除
            field=models.CharField(default='hoge', max_length=40, null=True),
            preserve_default=False,
        ),

        ## この行を追加
        migrations.RunPython(set_default_code, reverse_code=migrations.RunPython.noop),

        ## これも追加
        migrations.AlterField(
            model_name='profile',
            name='user_name',
            field=models.CharField(max_length=40, unique=True),
            preserve_default=False,
        ),
    ]

多分これでいけるはず。

ときにはこうやってマイグレーションファイルを直接いじることも必要なんだなと。

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