ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Django CharField 에서 ForeignKey 로 변경
    Django 2021. 4. 14. 11:16

     

    기존 모델에서 

     

    category = models.CharField('카테고리', max_length=100)

     

    이런 칼럼이 있는 경우, 바로 ForeignKey 로 변경하게 되면 

     

    django.db.utils.DataError: invalid input syntax for integer: " "

    이러한 에러를 마주하게 된다.

     

    바로 ForeignKey로 변경하면 데이터 보전도 하기 어렵기 때문에

     

    다음과 같은 방법으로 변경해보았습니다.

     

     

    우선, 다음처럼 CategoryModel 을 생성합니다.

    class CategoryModel(TimeStampedModel):
        name = models.CharField('카테고리 이름', max_length=55)
    
        def __str__(self):
            return self.name
    
        class Meta:
            db_table = 'tbl_category'

     

    그리고 난 후,

    category = models.CharField('카테고리', max_length=100)

    바로 아래에

    category_link = models.ForeignKey(CategoryModel, verbose_name='카테고리',
                                     on_delete=models.PROTECT,
                                     related_name='~~~',
                                     db_column='category_link'
                                     )

    위처럼 만들어 줍니다.

     

    그 이후 

    ./manage.py makemigrations --empty --name transfer_categorys 대상 앱 이름

     

    실행하게되면 다음과 비슷하게 생성되게 됩니다.

    from django.db import migrations
    
    
    class Migration(migrations.Migration):
    
        dependencies = [
            ('core', '0006_auto_20200402_1119'),
        ]
    
        operations = [
        ]

     

    여기서 다음 코드처럼 def link_categorys 와 migrations.RunPython(link_categorys) 을 

    추가해 준 뒤 migrate 를 시켜주게 되면 원래 있던 카테고리 텍스트 정보를 CategoryModel 쪽에 넣은뒤 

    해당 키 값을 category_link 에 추가로 넣고 저장하게 됩니다.

    from django.db import migrations
    
    
    def link_categorys(apps, schema_editor):
        대상모델 = apps.get_model('core', '대상모델')
        CategoryModel = apps.get_model('core', 'CategoryModel')
        for object_model in ObjectModel.objects.all():
            category, created = CategoryModel.objects.get_or_create(name=object_model.category)
            object_model.category_link = category
            object_model.save()
    
    
    class Migration(migrations.Migration):
    
        dependencies = [
            ('core', '0006_auto_20200402_1119'),
        ]
    
        operations = [
            migrations.RunPython(link_categorys),
        ]

     

    그러고 난 뒤,

    기존 category CharField는 삭제 후, makemigrations,

    category_link 를 category 로 변경 후, makemigrations,

    db_column 이름의 category_link 를 category  로 변경 후, makemigrations

     

    이후 migrate 까지 해주게 되면 CharField 에서 ForeignKey 로 변경이 끝나게 됩니다.

Designed by Tistory.