Django에서 사용자 지정 마이그레이션 작성

20173 단어 django
Django의 마이그레이션은 필드 생성, 수정 또는 삭제 여부에 관계없이 테이블의 구조에 변경 사항을 적용하는 애플리케이션 모델에서 자동 생성된 파일입니다.

새 필드를 추가하거나 사용자 지정 마이그레이션을 작성해야 하는 몇 가지 수정 작업을 수행하는 경우가 있습니다.🤔

보자.

문제



신발과 컴퓨터를 판매하는 전자 상거래 애플리케이션이 있습니다. (이상한 예지만 그렇게 하면 됩니다😂)

데이터베이스에는 다음 두 개의 테이블이 있습니다.

from django.db import models


class Shoe(models.Model):
    name = models.CharField(max_length=100)
    brand = models.CharField(max_length=100)
    color = models.CharField(max_length=100)
    price = models.IntegerField()
    in_stock = models.BooleanField(default=True)
    description = models.TextField()
    image = models.ImageField(upload_to='images/')

    def __str__(self):
        return self.name

class Computer(models.Model):
    name = models.CharField(max_length=100)
    brand = models.CharField(max_length=100)
    color = models.CharField(max_length=100)
    price = models.IntegerField()
    in_stock = models.BooleanField(default=True)
    description = models.TextField()
    image = models.ImageField(upload_to='images/')

    def __str__(self):
        return self.name


기본적으로 동일한 필드가 있는 Computer 테이블과 Shoe 테이블이 있습니다. 이를 개선하고 DRY를 방지하는 방법은 AbstractModel 클래스를 생성하는 것이지만 데이터베이스에서 그렇게 많이 계산되지는 않습니다.

동일한 필드와 Product 제품 유형을 알 수 있는 product_type 또는 computer 필드가 있는 shoe라는 클래스를 만들어 봅시다.

class Product(models.Model):

    PRODUCT_TYPE_CHOICES = (
        ('shoe', 'shoe'),
        ('computer', 'shoe'),
    )

    name = models.CharField(max_length=100)
    brand = models.CharField(max_length=100)
    color = models.CharField(max_length=100)
    price = models.IntegerField()
    in_stock = models.BooleanField(default=True)
    description = models.TextField()
    image = models.ImageField(upload_to='images/')
    product_type = models.CharField(max_length=100, choices=PRODUCT_TYPE_CHOICES)

    def __str__(self):
        return self.name


Product 클래스가 생성됩니다. 이제 뭐? 아마도 python manage.py makemigrationspython manage.py migrate 명령을 실행하여 데이터베이스에 변경 사항을 적용할 것입니다.Product 테이블이 생성되지만 제거할 수 있도록 이 새 테이블에 ShoeComputer 테이블 데이터도 포함하려고 합니다.
이렇게 하려면 사용자 지정 마이그레이션을 작성해야 합니다.

Django 프로젝트에서 product라는 분리된 Django 애플리케이션을 만들었다고 가정하면 다음 명령을 사용하여 product 애플리케이션에서 새로운 빈 마이그레이션 파일을 생성할 수 있습니다.

python manage.py makemigrations product --empty 


우리는 이와 비슷한 파일을 갖게 될 것입니다.

# Generated by Django 4.0.2 on 2022-04-03 10:36

from django.db import migrations


class Migration(migrations.Migration):

    dependencies = [
        ('product', '0001_initial'),
    ]

    operations = [
    ]


엄청난! 이제 ShoeComputer 모델을 가져오고 ShoeComputer 테이블 데이터를 Product 테이블로 마이그레이션하는 함수를 작성해야 합니다.

def migrate_to_product_model(apps, schema_editor):
    Product = apps.get_model('product', 'Product')
    Shoes = apps.get_model('shoe', 'Shoes')
    Computer = apps.get_model('computer', 'Computer')

    for shoe in Shoes.objects.all():
        Product.objects.create(
            name=shoe.name,
            brand=shoe.brand,
            color=shoe.color,
            in_stock=shoe.in_stock,
            description=shoe.description,
            image=shoe.image,
            product_type="shoe"
        )

    for computer in Computer.objects.all():
        Product.objects.create(
            name=computer.name,
            brand=computer.brand,
            color=computer.color,
            in_stock=computer.in_stock,
            description=computer.description,
            image=computer.image,
            product_type="computer"
        )


그리고 여기에 최종 마이그레이션 코드가 있습니다.

# Generated by Django 4.0.2 on 2022-04-03 10:36

from django.db import migrations

def migrate_to_product_model(apps, schema_editor):
    Product = apps.get_model('product', 'Product')
    Shoes = apps.get_model('shoe', 'Shoes')
    Computer = apps.get_model('computer', 'Computer')

    for shoe in Shoes.objects.all():
        Product.objects.create(
            name=shoe.name,
            brand=shoe.brand,
            color=shoe.color,
            in_stock=shoe.in_stock,
            description=shoe.description,
            image=shoe.image,
            product_type="shoe"
        )

    for computer in Computer.objects.all():
        Product.objects.create(
            name=computer.name,
            brand=computer.brand,
            color=computer.color,
            in_stock=computer.in_stock,
            description=computer.description,
            image=computer.image,
            product_type="computer"
        )


class Migration(migrations.Migration):

    dependencies = [
        ('product', '0001_initial'),
    ]

    operations = [
        migrations.RunPython(migrate_to_product_model)
    ]


이것은 사용자 지정 마이그레이션의 예입니다. 마이그레이션이 실패하고 데이터베이스가 엉망이 되어도 걱정할 필요가 없습니다. 마이그레이션 트랜잭션은 기본적으로 원자적이며 무언가 잘못되면 변경 사항이 데이터베이스에 커밋되지 않습니다.
🚀

자세한 내용은 Django의 official documentation of migrations을 확인하세요.

bloggu.io을(를) 사용하여 게시된 기사. 무료로 사용해 보세요.

좋은 웹페이지 즐겨찾기