Skip to content

renanstn/django-migrations-study

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

12 Commits
 
 
 
 
 
 
 
 

Repository files navigation

django-migrations-study

Python Django

Repositório utilizado para estudar migração de dados utilizando o Django

Situação

Aqui fiz um app, onde inicialmente eu tinha uma model Book, e nessa mesma model ficavam as seguintes informações sobre livros:

  • Id
  • Título
  • Páginas
  • Autor

Nessa situação fictícia, eu preciso separar os autores em uma model separada, e utilizarei as migrations do Django para isso.

Ao final do processo, a model Book deve conter os campos:

  • Id
  • Título
  • Páginas
  • Autor (ForeignKey)

E a model Author deve conter:

  • Id
  • Nome

Passo a passo

Nessa simulação, a model Book foi inicialmente declarada assim:

class Book(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4)
    title = models.CharField(max_length=255)
    pages = models.IntegerField()
    author = models.CharField(max_length=255)

O primeiro passo, foi criar a model Author:

class Author(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4)
    name = models.CharField(max_length=255)
  • Aqui eu gerei uma migration

Segundo passo, adicionar na model Book, o campo do tipo ForeignKey que fará o vínculo do livro com o autor. Importante manter inicialmente este campo com default=None e null=True,:

class Book(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4)
    title = models.CharField(max_length=255)
    pages = models.IntegerField()
    author = models.CharField(max_length=255)
    author_foreign_key = models.ForeignKey(
        Author,
        on_delete=models.CASCADE,
        default=None,
        null=True,
        blank=True,
    )
  • Aqui eu gerei uma migration

Agora o momento principal: Eu crio uma migration vazia, com o comando:

python manage.py makemigrations core --empty

Isso nos da uma migration vazia com o seguinte templade:

# Generated by Django 4.0.1 on 2022-01-06 00:09

from django.db import migrations


class Migration(migrations.Migration):

    dependencies = [
        ('core', '0003_book_author_foreign_key'),
    ]

    operations = [
    ]

Renomeei essa migration para 0004_separate_authors_from_books.py

É aqui que vou escrever a lógica da migração dos dados

Talvez você precise alterar o "dono" do arquivo para poder editá-lo, caso seja necessário, utilize o comando:

sudo chown $USER 0004_separate_authors_from_books.py

A migration com a lógica completa de separação dos dados ficou assim:

from django.db import migrations


class Migration(migrations.Migration):

    def create_authors_from_books(apps, schema_editor):
        model_book = apps.get_model("core", "Book")
        model_author = apps.get_model("core", "Author")

        books = model_book.objects.all()

        for book in books:
            author, _ = model_author.objects.get_or_create(
                name=book.author
            )
            book.author_foreign_key = author
            book.save()

    def reverse_create_authors_from_books(apps, schema_editor):
        model_book = apps.get_model("core", "Book")
        model_author = apps.get_model("core", "Author")

        books = model_book.objects.all()

        for book in books:
            book.author_foreign_key = None
            book.save()

        model_author.objects.all().delete()

    dependencies = [
        ('core', '0003_book_author_foreign_key'),
    ]

    operations = [
        migrations.RunPython(
            create_authors_from_books, reverse_create_authors_from_books
        )
    ]

TODO: Explicar melhor os métodos criados aqui.

  • Aqui eu executei a migration criada acima

Com os dados migrados, eu removo o campo author da model Book

  • Aqui eu gerei uma migration

Por último, eu renomeio o field author_foreign_key para um nome mais descente, no caso, author mesmo.

  • Aqui eu gerei uma migration

About

Um pequeno estudo sobre migração de dados em Django.

Topics

Resources

Stars

Watchers

Forks