Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

renanstn/django-migrations-study

Open more actions menu

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

Morty Proxy This is a proxified and sanitized view of the page, visit original site.