<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Izabela Guerreiro</title>
    <description>Blog pessoal, que tratará de assuntos relacionados a Tecnologia da Informação.</description>
    <link>http://izaguerreiro.me/</link>
    <atom:link href="http://izaguerreiro.me/feed.xml" rel="self" type="application/rss+xml" />
    <pubDate>Sat, 04 Jul 2020 21:08:10 +0000</pubDate>
    <lastBuildDate>Sat, 04 Jul 2020 21:08:10 +0000</lastBuildDate>
    <generator>Jekyll v3.8.7</generator>
    
      <item>
        <title>Como migrar um campo Charfield para ForeignKey com o banco de dados já populado em Django?</title>
        <description>&lt;p&gt;É comum que no decorrer de um projeto precisemos alterar a estrutura dos dados, seja por melhorias técnicas ou por necessidades da área de negócios. No meu caso uma necessidade da área de negócios em melhorar a usabilidade do django admin me levou a ter que migrar um campo do tipo Charfield para ForeignKey. Mas como fazer isso com o banco de dados populado e sem impactar os usuários?&lt;/p&gt;

&lt;p&gt;Vamos imaginar um sistema de administração de livraria, atualmente ele possui a seguinte estrutura, um app chamado &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bookstore&lt;/code&gt; que contém o seguinte model:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;from django.db import models


class Book(models.Model):
    title = models.Charfield(max_length=255)
    pages = models.IntegerField()
    author = models.Charfield(max_length=255)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Imaginando que o nome dos autores começaram a se repetir muito, criaremos um novo modelo para salvar os autores.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;from django.db import models


class Book(models.Model):
    title = models.Charfield(max_length=255)
    pages = models.IntegerField()
    author = models.Charfield(max_length=255)


class Author(models.Model):
    name = models.Charfield(max_length=255)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Criaremos nossa migration, ela será responsável por criar a tabela &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Author&lt;/code&gt; no banco de dados.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;./manage.py makemigrations
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Agora que temos o model &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Author&lt;/code&gt; iremos adicionar uma ForeignKey &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;author_id&lt;/code&gt; no model &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Book&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;from django.db import models


class Book(models.Model):
    title = models.Charfield(max_length=255)
    pages = models.IntegerField()
    author = models.Charfield(max_length=255)
    author_id = models.ForeignKey(max_length=255)


class Author(models.Model):
    name = models.Charfield(max_length=255)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Feito isso, precisaremos gerar uma nova migration, para que essas alterações sejam aplicadas no banco de dados, mas agora teremos que criar uma migração vazia, pois queremos adicionar os registros existentes em &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;author&lt;/code&gt; em nossa nova tabela &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Author&lt;/code&gt;. Para saber mais sobre migrações vazias &lt;a href=&quot;https://docs.djangoproject.com/en/3.0/topics/migrations/#data-migrations&quot;&gt;clique aqui&lt;/a&gt;&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;./manage.py makemigrations --empty bookstore
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Com nossa migration vazia criada, iremos criar uma função que salvará os registros do campo &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;author&lt;/code&gt; na tabela &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Author&lt;/code&gt; e em seguida iremos editar a campo &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;author&lt;/code&gt; inserindo o objeto &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Author&lt;/code&gt;. Nosso arquivo de migração ficará assim:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;from django.db import migrations


def transfer_author(apps, schema_editor):
    &quot;&quot;&quot; Transfer the author field from the Book model to the Author model. &quot;&quot;&quot;

    Book = apps.get_model(&quot;bookstore&quot;, &quot;Book&quot;)
    Author = apps.get_model(&quot;bookstore&quot;, &quot;Author&quot;)

    for book in Book.objects.all():
        author, created = Author.objects.get_or_create(name=book.author)
        book.author = author
        book.save()


class Migration(migrations.Migration):

    dependencies = [
        ('bookstore', '0002_auto_20200518_0305'),
    ]

    operations = [
        migrations.RunPython(transfer_author),
    ]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;O próximo passo é remover o campo &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;author&lt;/code&gt;, pois ele não será mais utilizado.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;from django.db import models


class Book(models.Model):
    title = models.Charfield(max_length=255)
    pages = models.IntegerField()
    author_id = models.ForeignKey(max_length=255)


class Author(models.Model):
    name = models.Charfield(max_length=255)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Criaremos uma nova migração.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;./manage.py makemigrations
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Agora podemos renomear o campo &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;author_id&lt;/code&gt; para &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;author&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;from django.db import models


class Book(models.Model):
    title = models.Charfield(max_length=255)
    pages = models.IntegerField()
    author = models.ForeignKey(max_length=255)


class Author(models.Model):
    name = models.Charfield(max_length=255)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Essa será a última migração que criaremos.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;./manage.py makemigrations
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;E por fim aplicaremos nossas migrações, utilizando o seguinte comando:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;./manage.py migrate
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Isso é tudo pessoal!!! Espero ter lhe ajudado de alguma forma. :)&lt;/p&gt;
</description>
        <pubDate>Sat, 04 Jul 2020 09:30:00 +0000</pubDate>
        <link>http://izaguerreiro.me/2020/07/04/como-migrar-um-campo-charfield-para-foreignkey-com-o-banco-ja-populado/</link>
        <guid isPermaLink="true">http://izaguerreiro.me/2020/07/04/como-migrar-um-campo-charfield-para-foreignkey-com-o-banco-ja-populado/</guid>
        
        
      </item>
    
  </channel>
</rss>
