<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Fernando Karchiloff</title>
    <description>The latest articles on Forem by Fernando Karchiloff (@ferkarchiloff).</description>
    <link>https://forem.com/ferkarchiloff</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F380026%2F059858c3-a7da-440c-ace7-a40e36b7ca66.jpeg</url>
      <title>Forem: Fernando Karchiloff</title>
      <link>https://forem.com/ferkarchiloff</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/ferkarchiloff"/>
    <language>en</language>
    <item>
      <title>How to debug Django inside a Docker container with VSCode</title>
      <dc:creator>Fernando Karchiloff</dc:creator>
      <pubDate>Fri, 26 Jan 2024 16:46:23 +0000</pubDate>
      <link>https://forem.com/ferkarchiloff/how-to-debug-django-inside-a-docker-container-with-vscode-4ef9</link>
      <guid>https://forem.com/ferkarchiloff/how-to-debug-django-inside-a-docker-container-with-vscode-4ef9</guid>
      <description>&lt;p&gt;&lt;em&gt;“If you want a thing done well, do it yourself.” ― Napoleon Bonaparte&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This tutorial is valid for these platforms:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Linux ✅&lt;/li&gt;
&lt;li&gt;Windows ❌&lt;/li&gt;
&lt;li&gt;OSX ❌&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Changes will be indicated along with a changelog.&lt;/p&gt;

&lt;h2&gt;
  
  
  Table Of Contents
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Table Of Contents&lt;/li&gt;
&lt;li&gt;1. Requirements&lt;/li&gt;
&lt;li&gt;2. Motivation&lt;/li&gt;
&lt;li&gt;
3. How to set up for this example

&lt;ul&gt;
&lt;li&gt;3.1. Clone the project and have some requirements ready&lt;/li&gt;
&lt;li&gt;3.2. Enable virtual environment&lt;/li&gt;
&lt;li&gt;3.3. Add debugpy&lt;/li&gt;
&lt;li&gt;3.4. Install the packages for definitions&lt;/li&gt;
&lt;li&gt;3.5. Build the project for Docker&lt;/li&gt;
&lt;li&gt;3.6. Create the debug file&lt;/li&gt;
&lt;li&gt;3.7. Create the launch.json file to allow VSCode to attach to our application&lt;/li&gt;
&lt;li&gt;3.8. Create a test view&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

4. Debugging your code

&lt;ul&gt;
&lt;li&gt;4.1. Execution of docker compose up with debug&lt;/li&gt;
&lt;li&gt;4.2. Attach debugger to application&lt;/li&gt;
&lt;li&gt;4.3. Request the URL and debug your code&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

5. Debugging library code

&lt;ul&gt;
&lt;li&gt;5.1. Changing &lt;code&gt;launch.json&lt;/code&gt; to work with library code&lt;/li&gt;
&lt;li&gt;5.2. Configuring variables for library code debug&lt;/li&gt;
&lt;li&gt;5.3. Debugging the library code&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;6. Conclusion&lt;/li&gt;

&lt;li&gt;

7. References

&lt;ul&gt;
&lt;li&gt;7.1 Docker Engine and Docker Compose&lt;/li&gt;
&lt;li&gt;7.2 Pyenv&lt;/li&gt;
&lt;li&gt;7.3 Poetry&lt;/li&gt;
&lt;li&gt;7.4 Git&lt;/li&gt;
&lt;li&gt;7.5 Project&lt;/li&gt;
&lt;li&gt;7.6 Debugpy&lt;/li&gt;
&lt;li&gt;7.7 VSCode&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  1. Requirements
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.docker.com/engine/install/" rel="noopener noreferrer"&gt;Docker Engine&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://docs.docker.com/compose/install/linux/#install-the-plugin-manually" rel="noopener noreferrer"&gt;Docker Compose v2.23.3&lt;/a&gt; (v2.24.1 has a bug when using two docker-compose.yml files that override)&lt;/li&gt;
&lt;li&gt;Python version manager &lt;a href="https://github.com/pyenv/pyenv" rel="noopener noreferrer"&gt;pyenv&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Python &amp;gt;= 3.8 (for this example, 3.11.x is used) through &lt;code&gt;pyenv&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Package manager &lt;a href="https://python-poetry.org/docs/#installation" rel="noopener noreferrer"&gt;Poetry&lt;/a&gt; v1.4.2&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://code.visualstudio.com/" rel="noopener noreferrer"&gt;VSCode&lt;/a&gt; editor at least v1.85&lt;/li&gt;
&lt;li&gt;Python package &lt;a href="https://github.com/microsoft/debugpy" rel="noopener noreferrer"&gt;debugpy&lt;/a&gt; &amp;gt;= 1.8&lt;/li&gt;
&lt;li&gt;For this demonstration, this project will be used: &lt;a href="https://github.com/wiamsuri/django-gunicorn-nginx-docker" rel="noopener noreferrer"&gt;https://github.com/wiamsuri/django-gunicorn-nginx-docker&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  2. Motivation
&lt;/h2&gt;

&lt;p&gt;Many tutorials available online don't acknowledge the problems of debbuging Django applicants with Docker, usually they explain basic functioning and sometimes are just as vague on how it works. My intention is explaining how to set up a debugger for Django applications that use Docker, Poetry and VSCode, correctly.&lt;/p&gt;

&lt;p&gt;One main problem that I constantly see is the &lt;strong&gt;debugpy&lt;/strong&gt; module always being installed when executing the container for debugging, which consumes bandwidth and time. It should be &lt;strong&gt;installed as a development dependency&lt;/strong&gt; for the project, so you can always use it when needed.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. How to set up for this example
&lt;/h2&gt;

&lt;p&gt;If you already have an project configured with &lt;code&gt;pyenv&lt;/code&gt;, Poetry and Docker. &lt;strong&gt;Skip steps 1, 2 and 8&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  3.1. Clone the project and have some requirements ready
&lt;/h3&gt;

&lt;p&gt;Install the &lt;code&gt;pyenv&lt;/code&gt; Python version manager, there are various ways to do it &lt;a href="https://github.com/pyenv/pyenv#installation" rel="noopener noreferrer"&gt;here&lt;/a&gt;. My personal choice is the automatic installer. Also check the &lt;a href="https://github.com/pyenv/pyenv#set-up-your-shell-environment-for-pyenv" rel="noopener noreferrer"&gt;shell set up&lt;/a&gt;, it will enable your environment to always have &lt;code&gt;pyenv&lt;/code&gt; easily from your terminal.&lt;/p&gt;

&lt;p&gt;After that, install the latest Python version available of &lt;code&gt;3.11&lt;/code&gt;, do it using the following:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

pyenv &lt;span class="nb"&gt;install &lt;/span&gt;3.11


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;As soon as you installed the specific Python version, install the Poetry package manager. I recommend using the &lt;a href="https://python-poetry.org/docs/#installing-with-the-official-installer" rel="noopener noreferrer"&gt;official installer&lt;/a&gt;, once done, proceed to clone the repository.&lt;/p&gt;

&lt;p&gt;Clone the project using &lt;a href="https://git-scm.com/" rel="noopener noreferrer"&gt;Git&lt;/a&gt;:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

git clone https://github.com/wiamsuri/django-gunicorn-nginx-docker


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;You will need to specify the Python version to &lt;code&gt;3.11.x&lt;/code&gt; at the root of the project:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

pyenv &lt;span class="nb"&gt;local &lt;/span&gt;3.11.&amp;lt;hotfix_version_installed&amp;gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;At this point, I'm assuming you also have the &lt;strong&gt;Docker Engine&lt;/strong&gt; and &lt;strong&gt;Docker Compose V2&lt;/strong&gt; installed.&lt;/p&gt;

&lt;h3&gt;
  
  
  3.2. Enable virtual environment
&lt;/h3&gt;

&lt;p&gt;Enable the virtual environment. If you don't have one, it will create for you with the command below:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

poetry shell


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  3.3. Add debugpy
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;debugpy&lt;/code&gt; description from it's &lt;a href="https://github.com/microsoft/debugpy" rel="noopener noreferrer"&gt;repository&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;An implementation of the Debug Adapter Protocol for Python 3.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It is a module maintained by Microsoft in order to debug Python programs, allowing connection to a debugger.&lt;/p&gt;

&lt;p&gt;If the project does not have the &lt;code&gt;debugpy&lt;/code&gt; module, add it with the command below:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

poetry add &lt;span class="nt"&gt;--group&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;dev debugpy


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Done this way, &lt;code&gt;debugpy&lt;/code&gt; will always be available at development and you won't consume bandwidth and lose your time waiting for the debugger module to install everytime.&lt;/p&gt;

&lt;h3&gt;
  
  
  3.4. Install the packages for definitions
&lt;/h3&gt;

&lt;p&gt;The command below will install all the packages needed for the project so VSCode can identify the packages in the source code. This step is needed to allow definitions for library's to be available:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

poetry &lt;span class="nb"&gt;install&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  3.5. Build the project for Docker
&lt;/h3&gt;

&lt;p&gt;Our project example has a &lt;code&gt;README.md&lt;/code&gt; file which explains how to build the project, each project has it's own configuration and explanations on how to build them. You can read it &lt;a href="https://github.com/wiamsuri/django-gunicorn-nginx-docker#for-development" rel="noopener noreferrer"&gt;here&lt;/a&gt; or use the following commands sequentially:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="nb"&gt;cp &lt;/span&gt;django.env.example django.env


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

docker compose build


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  3.6. Create the debug file
&lt;/h3&gt;

&lt;p&gt;This file is essential to allow debugging, as it will reuse all configurations defined in other files and only changes what is needed to accomplish our task.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;At the same level of &lt;code&gt;docker-compose.yml&lt;/code&gt;, create a new file called &lt;code&gt;docker-compose.debug.yml&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;It should have the service you need to debug, as also the &lt;code&gt;ports&lt;/code&gt; and &lt;code&gt;command&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;It must have the same port used for the application and debug port defined.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;File example:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;

&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;3.7"&lt;/span&gt;

&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;8000:8000"&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;5678:5678"&lt;/span&gt;
    &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;sh"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;-c"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;python3&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;-m&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;debugpy&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;--listen&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;0.0.0.0:5678&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;manage.py&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;runserver&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;0.0.0.0:8000"&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;As shown in the file, it's calling the &lt;code&gt;debugpy&lt;/code&gt; module and listening for connections at the port &lt;code&gt;5678&lt;/code&gt;, but it isn't waiting the connection of the debugger, it will run the application just as normal. If you need to wait for it to connect, you might need the flag &lt;code&gt;--wait-for-client&lt;/code&gt;, then the application will only start when the debugger is connected. Check more information in the &lt;code&gt;debugpy&lt;/code&gt; module documentation.&lt;/p&gt;

&lt;h3&gt;
  
  
  3.7. Create the launch.json file to allow VSCode to attach to our application
&lt;/h3&gt;

&lt;p&gt;In case you don't have a &lt;code&gt;launch.json&lt;/code&gt; file, create one. VSCode offers a template as default.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F64r976oaybfog7kgoyq8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F64r976oaybfog7kgoyq8.png" alt="Run and debug tab showing how to configure it"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click on &lt;strong&gt;create a launch.json file&lt;/strong&gt;.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;You might need to select the debugger, choose &lt;code&gt;Python&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Then choose the debug configuration, go for &lt;code&gt;Remote Attach&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;It will ask configurations for the remote debugging, stick with the default, or change to your needs.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The result will be something like this:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Use&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;IntelliSense&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;learn&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;about&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;possible&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;attributes.&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Hover&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;view&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;descriptions&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;of&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;existing&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;attributes.&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;For&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;more&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;information&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;visit:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;https://go.microsoft.com/fwlink/?linkid=&lt;/span&gt;&lt;span class="mi"&gt;830387&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"0.2.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"configurations"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Python: Remote Attach"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"python"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"request"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"attach"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"connect"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"host"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"localhost"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"port"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5678&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"pathMappings"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"localRoot"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"${workspaceFolder}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"remoteRoot"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"."&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"justMyCode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;


&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Change the property&lt;/strong&gt; &lt;code&gt;justMyCode&lt;/code&gt; to &lt;strong&gt;false&lt;/strong&gt;, so that the debugger can have access to code from the library that your code might call to see it's behavior.&lt;/p&gt;

&lt;h3&gt;
  
  
  3.8. Create a test view
&lt;/h3&gt;

&lt;p&gt;As the project is just an example, it has a basic template for running Django with Docker. We have to create a view to test our debugger and check if it's running correctly.&lt;/p&gt;

&lt;p&gt;At the &lt;code&gt;urls.py&lt;/code&gt; file, in the &lt;code&gt;config/&lt;/code&gt; folder, create a &lt;code&gt;hello_view&lt;/code&gt; function and add it to the &lt;code&gt;urlpatterns&lt;/code&gt; list.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;django.contrib&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;admin&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;django.http&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;HttpResponse&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;django.urls&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;hello_view&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;method&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;GET&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;HttpResponse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hello, world!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;urlpatterns&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="nf"&gt;path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;admin/&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;admin&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;site&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;urls&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nf"&gt;path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;hello/&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;hello_view&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;With this function, the debugger will be able to stop the execution of our code and check what's happening inside the program.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Debugging your code
&lt;/h2&gt;

&lt;h3&gt;
  
  
  4.1. Execution of docker compose up with debug
&lt;/h3&gt;

&lt;p&gt;If everything was done correctly, we can start our application with the debugging command. In order for this event to happen, specify the debug file in the command. Do it as follows:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

docker compose &lt;span class="nt"&gt;-f&lt;/span&gt; docker-compose.yml &lt;span class="nt"&gt;-f&lt;/span&gt; docker-compose.debug.yml up


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The &lt;strong&gt;Docker Compose&lt;/strong&gt; will overlap the files and use the debug file specified. As it's using a debug file, a base file must be determined for the services. As you may have other &lt;code&gt;docker-compose&lt;/code&gt; files, just ensure the &lt;code&gt;docker-compose.debug.yml&lt;/code&gt; is the last one, so the program can overlap the files and get their configurations correctly.&lt;/p&gt;

&lt;h3&gt;
  
  
  4.2. Attach debugger to application
&lt;/h3&gt;

&lt;p&gt;With the application running, select the "Run and Debug" tab at VSCode, it will look like this if the &lt;code&gt;launch.json&lt;/code&gt; file is present:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flgp7jvr31sa70iyv84eg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flgp7jvr31sa70iyv84eg.png" alt="Image showing Run and Debug tab when it has a launch.json file"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click the play button indicated as &lt;strong&gt;Python: Remote Attach&lt;/strong&gt;. In normal scenarios, it will connect the debugger to your application and a toolbar will appear on screen.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkjrc0p6h3pn72s7c9719.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkjrc0p6h3pn72s7c9719.png" alt="VSCode with debugger toolbar"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This means the debugger is working now, let's test it.&lt;/p&gt;

&lt;h3&gt;
  
  
  4.3. Request the URL and debug your code
&lt;/h3&gt;

&lt;p&gt;Open your browser of choice and type &lt;code&gt;localhost:8000/hello/&lt;/code&gt;, a call to the test view will be made. The result should be a "Hello, world!":&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhm8dfqtk0bz9651pgjk9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhm8dfqtk0bz9651pgjk9.png" alt="Browser page with "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Notice that the debugger hasn't triggered yet, that's because we didn't specified any breakpoints in the code.&lt;/p&gt;

&lt;p&gt;Set up a breakpoint on line 22 (L22) by clicking on the left side of the line number:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhaz61faou2rhyqvhvvy0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhaz61faou2rhyqvhvvy0.png" alt="Line with breakpoint"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now we refresh the page and you will see the &lt;em&gt;magic&lt;/em&gt; happening.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7fl51opk727497abszt5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7fl51opk727497abszt5.png" alt="Code execution stopped at line 22"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Our code execution stopped at the breakpoint we've just specified, you will see variables, call stack and even watch for specific values or expressions. You can learn more about the debugger screen in the &lt;a href="https://code.visualstudio.com/docs/editor/debugging" rel="noopener noreferrer"&gt;VSCode documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;That's the basic to debug your code and see how it's behaving. However, &lt;strong&gt;this configuration does not allow to make breakpoints inside libraries&lt;/strong&gt; that you might have in your project.&lt;/p&gt;

&lt;p&gt;The next section will explain what's needed to do in order to debug libraries directly from inside your project.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Debugging library code
&lt;/h2&gt;

&lt;p&gt;Sometimes you're not interested in debugging your code. Instead, you want to understand the library logic or behavior in order to fix your code, or the library itself.&lt;/p&gt;

&lt;p&gt;In this scenario, we need breakpoints inside the library code. However, by default, the configuration created above (which solves most problems) isn't enough to allow debugging library code.&lt;/p&gt;

&lt;p&gt;Under these circumstances, you will get this grey empty dot:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiym4zp4ynuozppf492ac.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiym4zp4ynuozppf492ac.png" alt="Grey empty dot for breakpoint that does not work"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In order to solve this, changes are needed at the &lt;code&gt;launch.json&lt;/code&gt;, environment variables in &lt;code&gt;.bashrc&lt;/code&gt; and &lt;code&gt;settings.json&lt;/code&gt; to make it work.&lt;/p&gt;

&lt;h3&gt;
  
  
  5.1. Changing &lt;code&gt;launch.json&lt;/code&gt; to work with library code
&lt;/h3&gt;

&lt;p&gt;To make the debugger aware that the library code is available, some modifications are needed.&lt;/p&gt;

&lt;p&gt;To accomplish this, changes to &lt;code&gt;launch.json&lt;/code&gt; file must be done, so that the debugger can seek for the path were the library code is. By adding another object at &lt;code&gt;pathMappings&lt;/code&gt;, we make the code available to the debugger.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Use&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;IntelliSense&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;learn&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;about&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;possible&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;attributes.&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Hover&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;view&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;descriptions&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;of&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;existing&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;attributes.&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;For&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;more&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;information&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;visit:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;https://go.microsoft.com/fwlink/?linkid=&lt;/span&gt;&lt;span class="mi"&gt;830387&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"0.2.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"configurations"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Python: Remote Attach"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"python"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"request"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"attach"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"connect"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"host"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"localhost"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"port"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5678&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"pathMappings"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"localRoot"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"${workspaceFolder}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"remoteRoot"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"."&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"localRoot"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"${env:PACKAGES_ENV_PATH}/${config:python.poetry.project.venv}/lib/python3.11/site-packages/"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"remoteRoot"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/usr/local/lib/python3.11/site-packages/"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"justMyCode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;


&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;With this configuration provided for the debugger, which contains the library code path, it will seek for the files and allow to set a breakpoint.&lt;/p&gt;

&lt;p&gt;Although, I have to explain what is that object and how you can configure it.&lt;/p&gt;

&lt;h3&gt;
  
  
  5.2. Configuring variables for library code debug
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;${env:PACKAGES_ENV_PATH}&lt;/code&gt; is an environment variable defined in &lt;code&gt;.bashrc&lt;/code&gt; (or similar) that tells us where to look for the libraries source code. This path can be obtained by using:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

poetry &lt;span class="nb"&gt;env &lt;/span&gt;info &lt;span class="nt"&gt;--path&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The result will be similiar to:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

/home/youruser/.cache/pypoetry/virtualenvs/django-gunicorn-nginx-docker-ucLVPu3k-py3.11


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Until &lt;code&gt;virtualenvs/&lt;/code&gt;, the path leads to all virtual environments that your Poetry creates. After it, is the specific &lt;em&gt;virtualenv&lt;/em&gt; for the project.&lt;/p&gt;

&lt;p&gt;The environment variable VSCode needs to read, must be defined at &lt;code&gt;.bashrc&lt;/code&gt; (or similars) as:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="c"&gt;#VSCode debug&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;PACKAGES_ENV_PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"/home/youruser/.cache/pypoetry/virtualenvs"&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;After adding this piece of code to &lt;code&gt;.bashrc&lt;/code&gt;, VSCode must be restarted to allow the process to get the new defined &lt;em&gt;env&lt;/em&gt;.&lt;br&gt;
This process has to be done due to how VSCode is opened and how processes work, for more info, see &lt;a href="https://github.com/microsoft/vscode/issues/29679" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;${config:python.poetry.project.venv}&lt;/code&gt; is a user defined variable inside &lt;code&gt;settings.json&lt;/code&gt; which tells us which &lt;em&gt;virtualenv&lt;/em&gt; the debugger must look for.&lt;/p&gt;

&lt;p&gt;The last part of the command mentioned above can be used to fulfill this part. If the project doesn't have a &lt;code&gt;settings.json&lt;/code&gt; file, just create one under &lt;code&gt;.vscode/&lt;/code&gt; folder, in case you have it, define the new variable to use:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"python.poetry.project.venv"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"django-gunicorn-nginx-docker-ucLVPu3k-py3.11"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;


&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;I tried to came up with a key that won't affect the VSCode ecosystem or any extensions (that I've heard of).&lt;/p&gt;

&lt;p&gt;This was the best way I've found that allowed to easily define the path in order to share the &lt;code&gt;launch.json&lt;/code&gt; file with other coworkers through source control software.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Observation:&lt;/strong&gt; you can also hardcode the path to make your life easier, .&lt;/p&gt;

&lt;p&gt;The Python version won't change frequently, so I fixed it in the configuration.&lt;/p&gt;

&lt;p&gt;In this context, I'm assuming that &lt;code&gt;settings.json&lt;/code&gt; &lt;strong&gt;will never be commited&lt;/strong&gt; to the source control, and the user can change as he desires. If that's not the case, I would recommend to hardcode the path in the &lt;code&gt;localRoot&lt;/code&gt;, but every developer path will be different, &lt;strong&gt;be aware&lt;/strong&gt;. &lt;strong&gt;DO NOT FORGET&lt;/strong&gt; to never include this change to your commits.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;If you know about a better way to do this configuration for library source code debugging, let me know in the comments or reach out to me.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  5.3. Debugging the library code
&lt;/h3&gt;

&lt;p&gt;Commands are the same from the Debugging your code section, the only difference is where the breakpoint is indicated.&lt;/p&gt;

&lt;p&gt;For the example, I'd choosen the &lt;code&gt;WSGIHandler&lt;/code&gt; class as it's purpose is receiving the requests and serving them.&lt;/p&gt;

&lt;p&gt;I set the breakpoint at line 123 (L123). If the dot is red, it means the debugger can use the breakpoint properly. Then I refreshed the page for our test view, and this is the result:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs4oz27fj921nl3xv08tf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs4oz27fj921nl3xv08tf.png" alt="Debugger with execution stopped at line 123 where breakpoint was set"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;From there, you can happily (or not) debug the code.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Conclusion
&lt;/h2&gt;

&lt;p&gt;Debugging is not a easy task, but with this tutorial I expect that somehow I made your life easier. So you can achieve your objective and/or catch that bug that is annoying you.&lt;/p&gt;

&lt;p&gt;Feel free to comment and warn me about any mistakes that this article may have.&lt;/p&gt;

&lt;p&gt;Thanks for reading until here, Ferka out ✌️. &lt;/p&gt;

&lt;h2&gt;
  
  
  7. References
&lt;/h2&gt;

&lt;h3&gt;
  
  
  7.1 Docker Engine and Docker Compose
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.docker.com/engine/install/" rel="noopener noreferrer"&gt;https://docs.docker.com/engine/install/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://docs.docker.com/compose/install/linux/#install-the-plugin-manually" rel="noopener noreferrer"&gt;https://docs.docker.com/compose/install/linux/#install-the-plugin-manually&lt;/a&gt; (be aware of the v2.24.1 bug with overlap compose files)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  7.2 Pyenv
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/pyenv/pyenv" rel="noopener noreferrer"&gt;https://github.com/pyenv/pyenv&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/pyenv/pyenv#installation" rel="noopener noreferrer"&gt;https://github.com/pyenv/pyenv#installation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/pyenv/pyenv#set-up-your-shell-environment-for-pyenv" rel="noopener noreferrer"&gt;https://github.com/pyenv/pyenv#set-up-your-shell-environment-for-pyenv&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  7.3 Poetry
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://python-poetry.org/docs/#installation" rel="noopener noreferrer"&gt;https://python-poetry.org/docs/#installation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://python-poetry.org/docs/#installing-with-the-official-installer" rel="noopener noreferrer"&gt;https://python-poetry.org/docs/#installing-with-the-official-installer&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://python-poetry.org/docs/managing-environments/" rel="noopener noreferrer"&gt;https://python-poetry.org/docs/managing-environments/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  7.4 Git
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://git-scm.com/" rel="noopener noreferrer"&gt;https://git-scm.com/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  7.5 Project
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/wiamsuri/django-gunicorn-nginx-docker#for-development" rel="noopener noreferrer"&gt;https://github.com/wiamsuri/django-gunicorn-nginx-docker#for-development&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  7.6 Debugpy
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://stackoverflow.com/questions/76876915/pydev-debugger-unable-to-find-translation-for-please-revise-your-path-mapping" rel="noopener noreferrer"&gt;https://stackoverflow.com/questions/76876915/pydev-debugger-unable-to-find-translation-for-please-revise-your-path-mapping&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/microsoft/vscode-python-debugger/issues/158" rel="noopener noreferrer"&gt;https://github.com/microsoft/vscode-python-debugger/issues/158&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  7.7 VSCode
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://code.visualstudio.com/docs/editor/debugging#_launch-configurations" rel="noopener noreferrer"&gt;https://code.visualstudio.com/docs/editor/debugging#_launch-configurations&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://code.visualstudio.com/docs/editor/variables-reference#_configuration-variables" rel="noopener noreferrer"&gt;https://code.visualstudio.com/docs/editor/variables-reference#_configuration-variables&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://code.visualstudio.com/docs/editor/debugging" rel="noopener noreferrer"&gt;https://code.visualstudio.com/docs/editor/debugging&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://code.visualstudio.com/docs/python/environments" rel="noopener noreferrer"&gt;https://code.visualstudio.com/docs/python/environments&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://code.visualstudio.com/api/extension-guides/command" rel="noopener noreferrer"&gt;https://code.visualstudio.com/api/extension-guides/command&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://stackoverflow.com/questions/66971452/how-to-add-virtual-environment-to-vscode-launch-json" rel="noopener noreferrer"&gt;https://stackoverflow.com/questions/66971452/how-to-add-virtual-environment-to-vscode-launch-json&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/microsoft/vscode/issues/29679" rel="noopener noreferrer"&gt;https://github.com/microsoft/vscode/issues/29679&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.google.com/search?channel=fs&amp;amp;client=ubuntu-sn&amp;amp;q=how+to+populate+vscode+env" rel="noopener noreferrer"&gt;https://www.google.com/search?channel=fs&amp;amp;client=ubuntu-sn&amp;amp;q=how+to+populate+vscode+env&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://stackoverflow.com/questions/75767757/how-can-i-specify-environment-variables-for-the-vs-code-process-in-my-vs-code-se" rel="noopener noreferrer"&gt;https://stackoverflow.com/questions/75767757/how-can-i-specify-environment-variables-for-the-vs-code-process-in-my-vs-code-se&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://unix.stackexchange.com/questions/38205/change-environment-of-a-running-process" rel="noopener noreferrer"&gt;https://unix.stackexchange.com/questions/38205/change-environment-of-a-running-process&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://stackoverflow.com/questions/48595446/is-there-any-way-to-set-environment-variables-in-visual-studio-code" rel="noopener noreferrer"&gt;https://stackoverflow.com/questions/48595446/is-there-any-way-to-set-environment-variables-in-visual-studio-code&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://stackoverflow.com/questions/44303316/vscode-defining-own-variables-in-tasks-json" rel="noopener noreferrer"&gt;https://stackoverflow.com/questions/44303316/vscode-defining-own-variables-in-tasks-json&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>python</category>
      <category>docker</category>
      <category>vscode</category>
      <category>debug</category>
    </item>
    <item>
      <title>How to avoid messing up squash migration in Hasura</title>
      <dc:creator>Fernando Karchiloff</dc:creator>
      <pubDate>Thu, 05 Jan 2023 20:54:27 +0000</pubDate>
      <link>https://forem.com/ferkarchiloff/how-to-avoid-messing-up-squash-migration-in-hasura-1p88</link>
      <guid>https://forem.com/ferkarchiloff/how-to-avoid-messing-up-squash-migration-in-hasura-1p88</guid>
      <description>&lt;p&gt;&lt;a href="https://dev.to/ferkarchiloff/reduzindo-as-chances-de-errar-um-squash-de-migracoes-no-hasura-3c23"&gt;Versão em Português Brasileiro&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Summary
&lt;/h1&gt;

&lt;ol&gt;
&lt;li&gt;Technology versions&lt;/li&gt;
&lt;li&gt;Background knowledge needed&lt;/li&gt;
&lt;li&gt;Why I decided to write it&lt;/li&gt;
&lt;li&gt;Too long; didn't read&lt;/li&gt;
&lt;li&gt;Database example&lt;/li&gt;
&lt;li&gt;Squash guide&lt;/li&gt;
&lt;li&gt;Conclusion&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Technology versions
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Hasura v2.0.9&lt;/li&gt;
&lt;li&gt;Hasura CLI v2.0.9&lt;/li&gt;
&lt;li&gt;PostgreSQL 12&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Background knowledge needed
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Understand SQL and it's commands&lt;/li&gt;
&lt;li&gt;Understand how migrations work&lt;/li&gt;
&lt;li&gt;How &lt;a href="https://hasura.io/docs/latest/graphql/core/getting-started/index.html#getting-started" rel="noopener noreferrer"&gt;Hasura GraphQL Engine&lt;/a&gt; works&lt;/li&gt;
&lt;li&gt;How &lt;a href="https://git-scm.com/" rel="noopener noreferrer"&gt;Git&lt;/a&gt; works&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why I decided to write it
&lt;/h2&gt;

&lt;p&gt;During the development of one project at the e-commerce company I'd worked for, we had a task that would require to change the database structure, many tables and columns had to be changed to complete the task.&lt;/p&gt;

&lt;p&gt;As &lt;strong&gt;Hasura GraphQL Engine&lt;/strong&gt; offers a web page to make the structural changes at the database, I made the changes using this interface and executed the manual queries that were necessary. All of these modifications created migrations in the repository, as expected for a project with migrations enabled in Hasura.&lt;/p&gt;

&lt;p&gt;After the modifications, it was noticeable the amount of folders with modifications that were being saved in the migration format. I decided to use the command to compress all of them into a single file, which would be more readable. That's when my mistake happened: without making basic validations beforehand, I executed the command and deleted the previous migrations. That's how I spent more than a day trying to fix a mistake that could have been avoided with a simple checklist before using the command. How can we avoid this? I will explain in the next topics.&lt;/p&gt;

&lt;h2&gt;
  
  
  Too long; didn't read
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Make your changes using migrations.&lt;/li&gt;
&lt;li&gt;Using Git or similar, make a commit to save your migrations.&lt;/li&gt;
&lt;li&gt;Make sure that the &lt;code&gt;up.sql&lt;/code&gt; and &lt;code&gt;down.sql&lt;/code&gt; files execute as desired using &lt;code&gt;hasura migrate apply&lt;/code&gt; and &lt;code&gt;hasura migrate apply --down &amp;lt;N&amp;gt;&lt;/code&gt;. Do manual fixes (mistakes can happen) using the &lt;code&gt;SQL&lt;/code&gt; tab without using migrations.&lt;/li&gt;
&lt;li&gt;Commit your complete migrations to the version control system.&lt;/li&gt;
&lt;li&gt;Use the command &lt;code&gt;hasura migrate squash --from &amp;lt;num_migration&amp;gt; --name &amp;lt;name&amp;gt;&lt;/code&gt; to execute the &lt;em&gt;squash&lt;/em&gt;, delete the old migrations (you already have them at the version control).&lt;/li&gt;
&lt;li&gt;Mark the created migration as fulfilled at the database using &lt;code&gt;hasura migrate apply --skip-execution&lt;/code&gt; (if the removed migrations weren't applied, &lt;strong&gt;don't use&lt;/strong&gt; the flag).&lt;/li&gt;
&lt;li&gt;Use again the command &lt;code&gt;hasura migrate apply --down &amp;lt;N&amp;gt;&lt;/code&gt; to remove the migrations, and then use it without the flag to make sure that they're working.&lt;/li&gt;
&lt;li&gt;Commit your changes to the version control system.&lt;/li&gt;
&lt;li&gt;(Optional) Do optimizations if needed, for example: remove an &lt;code&gt;ALTER TABLE&lt;/code&gt; if there's a &lt;code&gt;DROP TABLE&lt;/code&gt; (without losing data of course).&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Database example
&lt;/h2&gt;

&lt;p&gt;To demonstrate how to do a &lt;em&gt;squash&lt;/em&gt; correctly, I will use a simple database with a single table, but in a real case you can have various operations among &lt;em&gt;N&lt;/em&gt; tables, which may lead to a larger and complex &lt;em&gt;squash&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Our database contains the &lt;code&gt;students&lt;/code&gt; table defined through this structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="nv"&gt;"public"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;"students"&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nv"&gt;"id"&lt;/span&gt; &lt;span class="nb"&gt;serial&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nv"&gt;"name"&lt;/span&gt; &lt;span class="nb"&gt;Text&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nv"&gt;"score"&lt;/span&gt; &lt;span class="nb"&gt;text&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It was created after we had already connected to our database created in PostgreSQL, disabled the console, and started migrations in the project. You can see more details on how to enable migrations in this &lt;a href="https://hasura.io/docs/latest/graphql/core/migrations/migrations-setup.html" rel="noopener noreferrer"&gt;section&lt;/a&gt; of &lt;em&gt;Migrations &amp;amp; Metadata (CI/CD)&lt;/em&gt; in the documentation for the &lt;em&gt;Hasura GraphQL Engine&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Let's say that this table was filled with some student data:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg1goo3fgozuc3tasrzz1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg1goo3fgozuc3tasrzz1.png" alt="Table with three columns called: " id=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Somewhere along the way, we realize that the data in the &lt;code&gt;score&lt;/code&gt; column, which cannot be text because we would like to do some arithmetic with them. However, we cannot change this data if it is being used in production! (Assume that you have thousands of important data and cannot lose them)&lt;/p&gt;

&lt;p&gt;What to do then? In the development environment, we will &lt;strong&gt;create a new column&lt;/strong&gt; to accommodate this data. We will name it &lt;code&gt;score_decimal&lt;/code&gt; because it represents the score as a decimal number allowing arithmetic operations. Go to the &lt;code&gt;students&lt;/code&gt; table's &lt;em&gt;Modify&lt;/em&gt; tab and click &lt;em&gt;Add new column&lt;/em&gt;. We will define it as a &lt;code&gt;Numeric&lt;/code&gt; column.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6iop7eaqomy9s2yt4u2o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6iop7eaqomy9s2yt4u2o.png" alt="Modify tab selected with option to add new column appearing with filled data"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once the new column is created, we can migrate the data from the &lt;code&gt;score&lt;/code&gt; column to &lt;code&gt;score_decimal&lt;/code&gt;. To do this, we will use the &lt;code&gt;SQL&lt;/code&gt; section located just below the tables in our database.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7euulbm2lsd9aq5v9gm2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7euulbm2lsd9aq5v9gm2.png" alt="Databases being displayed in the top tab and below it the SQL tab"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this tab you can run SQL code directly against the selected database, marking these queries as migrations or not. Depending on the code, Hasura may be smart enough to identify if it is a structural or data change and mark it as a migration automatically, so always pay attention before running the query to see if the "&lt;em&gt;This is a migration&lt;/em&gt;" box is enabled.&lt;/p&gt;

&lt;p&gt;Putting the query that converts the scores in the text field, we can run it without adding it as a migration in order to verify that the query is being executed as described. After checking, we can enable the migration box and write a name for it, I used a descriptive name &lt;code&gt;cast_students_score_to_decimal_migration&lt;/code&gt;. This is the query made to convert the data:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="n"&gt;students&lt;/span&gt;
&lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;score_decimal&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;CAST&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="nb"&gt;DECIMAL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;students&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;students&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7izhheuev7kw4gpd6ugo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7izhheuev7kw4gpd6ugo.png" alt="SQL tab with query filled in the text field and migration function enabled"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NOTE: always be careful when making structural changes that change field categories, so do it in steps and update the view layer (front-end), if used, to change the new type without breaking the application for clients.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;After running the update of the data, we can rename the columns and delete the old one. The name used for the migration was &lt;code&gt;rename_columns_and_remove_old_migration&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;ALTER&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;students&lt;/span&gt; &lt;span class="k"&gt;RENAME&lt;/span&gt; &lt;span class="k"&gt;COLUMN&lt;/span&gt; &lt;span class="nv"&gt;"score"&lt;/span&gt; &lt;span class="k"&gt;TO&lt;/span&gt; &lt;span class="nv"&gt;"score_text"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;ALTER&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;students&lt;/span&gt; &lt;span class="k"&gt;RENAME&lt;/span&gt; &lt;span class="k"&gt;COLUMN&lt;/span&gt; &lt;span class="nv"&gt;"score_decimal"&lt;/span&gt; &lt;span class="k"&gt;TO&lt;/span&gt; &lt;span class="nv"&gt;"score"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;ALTER&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;students&lt;/span&gt; &lt;span class="k"&gt;DROP&lt;/span&gt; &lt;span class="k"&gt;COLUMN&lt;/span&gt; &lt;span class="nv"&gt;"score_text"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm85kjzac5sndhxbljb4k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm85kjzac5sndhxbljb4k.png" alt="SQL tab with query filled in the text field and migration function enabled"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With that, we finished our modification to run our arithmetic operations, but we ended up with some separate migrations that can be joined through a &lt;code&gt;squash&lt;/code&gt; operation, as they can be executed all together.&lt;/p&gt;

&lt;h2&gt;
  
  
  Squash guide
&lt;/h2&gt;

&lt;p&gt;For the &lt;code&gt;squash&lt;/code&gt; process of the migrations to occur "correctly" (there can always be an unexpected error in the middle of the process), we need to ensure that some steps are followed. I will list some of them to avoid errors in this process.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Save the made migrations in the repository&lt;/li&gt;
&lt;li&gt;Ensure that the migrations can be made and undone without errors&lt;/li&gt;
&lt;li&gt;Save the complete migrations&lt;/li&gt;
&lt;li&gt;Squash the migrations&lt;/li&gt;
&lt;li&gt;Mark the migration as executed&lt;/li&gt;
&lt;li&gt;Save the changes&lt;/li&gt;
&lt;li&gt;(Optional) Modify the compressed migration as desired (and save the changes)&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  1. Save the made migrations in the repository
&lt;/h3&gt;

&lt;p&gt;To keep track of our migrations and not lose progress, we save the changes in a commit, we can then proceed to change them without the risk of losing what we have done, this was one of the mistakes I made earlier, not saving in the version control.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Ensure that the migrations can be made and undone without errors
&lt;/h3&gt;

&lt;p&gt;With the migrations saved in the repository, we can start modifying those that have incomplete &lt;code&gt;down.sql&lt;/code&gt; files. Many of the changes we make to the database do not always reflect in the files due to being complex changes, such as renaming columns and deleting a column in the same migration. For example, in the last migration, the &lt;code&gt;down.sql&lt;/code&gt; file was filled out as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Could not auto-generate a down migration.&lt;/span&gt;
&lt;span class="c1"&gt;-- Please write an appropriate down migration for the SQL below:&lt;/span&gt;
&lt;span class="c1"&gt;-- ALTER TABLE students RENAME COLUMN "score" TO "score_text";&lt;/span&gt;
&lt;span class="c1"&gt;-- ALTER TABLE students RENAME COLUMN "score_decimal" TO "score";&lt;/span&gt;
&lt;span class="c1"&gt;-- ALTER TABLE students DROP COLUMN "score_text";&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For the migration to work back, that is, remove the changes, we will reverse the commands made in &lt;code&gt;up.sql&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;ALTER&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;students&lt;/span&gt; &lt;span class="k"&gt;ADD&lt;/span&gt; &lt;span class="k"&gt;COLUMN&lt;/span&gt; &lt;span class="nv"&gt;"score_text"&lt;/span&gt; &lt;span class="nb"&gt;text&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;ALTER&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;students&lt;/span&gt; &lt;span class="k"&gt;RENAME&lt;/span&gt; &lt;span class="k"&gt;COLUMN&lt;/span&gt; &lt;span class="nv"&gt;"score"&lt;/span&gt; &lt;span class="k"&gt;TO&lt;/span&gt; &lt;span class="nv"&gt;"score_decimal"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;ALTER&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;students&lt;/span&gt; &lt;span class="k"&gt;RENAME&lt;/span&gt; &lt;span class="k"&gt;COLUMN&lt;/span&gt; &lt;span class="nv"&gt;"score_text"&lt;/span&gt; &lt;span class="k"&gt;TO&lt;/span&gt; &lt;span class="nv"&gt;"score"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We will do the same with the migration that creates the new column and reverse the command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;ALTER&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="nv"&gt;"public"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;"students"&lt;/span&gt; &lt;span class="k"&gt;DROP&lt;/span&gt; &lt;span class="k"&gt;COLUMN&lt;/span&gt; &lt;span class="nv"&gt;"score_decimal"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With that, we can use the &lt;code&gt;--up&lt;/code&gt; and &lt;code&gt;--down&lt;/code&gt; flags of &lt;code&gt;hasura migrate apply&lt;/code&gt;. The command changes the database according to the &lt;code&gt;.sql&lt;/code&gt; defined in the migrations. If you relate the files to their respective commands, it will make more sense, the command that uses &lt;code&gt;--down&lt;/code&gt; will remove the applied migration changes, while &lt;code&gt;--up&lt;/code&gt; will apply them (&lt;code&gt;--up&lt;/code&gt; is applied by default if not defined). To remove only some, use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;hasura migrate apply &lt;span class="nt"&gt;--down&lt;/span&gt; &amp;lt;N&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the command, &lt;em&gt;N&lt;/em&gt; is the number of migrations that will be removed. Use &lt;code&gt;hasura migrate apply --help&lt;/code&gt; to see more details.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note: If you ran a migration and it failed, if you have more than one SQL command in the same file, try to fix it through the &lt;code&gt;SQL&lt;/code&gt; tab (without creating a new one), correct it and try again.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Save the complete migrations
&lt;/h3&gt;

&lt;p&gt;Since you have tested your migrations and they are working, save them again in a commit, now with the complete migrations.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Squash the migrations
&lt;/h3&gt;

&lt;p&gt;With all migrations completed and working, we can &lt;em&gt;squash&lt;/em&gt; them, that is, compress them into a single migration. To do this, we will run the command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;hasura migrate squash &lt;span class="nt"&gt;--from&lt;/span&gt; &amp;lt;num_migracao&amp;gt; &lt;span class="nt"&gt;--name&lt;/span&gt; &amp;lt;name&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It compress the migration files for us. In this example, I will do like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;hasura migrate squash &lt;span class="nt"&gt;--from&lt;/span&gt; 1638852925395 &lt;span class="nt"&gt;--name&lt;/span&gt; &lt;span class="s2"&gt;"changing_column_type"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command will merge all migrations starting from the prefix &lt;code&gt;1638852925395&lt;/code&gt; into a single one, named &lt;em&gt;"changing_column_type"&lt;/em&gt;. I recommend you delete the previous migrations because they are already saved in the repository.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Mark the migration as executed
&lt;/h3&gt;

&lt;p&gt;Once we have created our new compressed migration as a result of the operation, &lt;strong&gt;if the previous migrations were not applied to the database&lt;/strong&gt;, we will run the command to mark it as if the migration we just generated had already been applied:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;hasura migrate apply &lt;span class="nt"&gt;--skip-execution&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Remember that this command should only be run if we actually applied the changes of the other migrations to the database, otherwise, run the command without the &lt;code&gt;--skip-execution&lt;/code&gt; flag to apply it normally.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Save the changes
&lt;/h3&gt;

&lt;p&gt;Once this is done, save the changes again in the repository's version control to avoid losing your changes.&lt;/p&gt;

&lt;h3&gt;
  
  
  7. (Optional) Modify the compressed migration as desired (and save the changes)
&lt;/h3&gt;

&lt;p&gt;If your migration has many commands, evaluate the file and see if, depending on the changes made, you can simplify the executed SQL code. For example, you create a table, and then in another migration you add a column, if you have not added any data in the middle of the way, or it has not gone to production yet, directly add the column when creating the table, which will simplify the code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;I hope that these instructions serve as a guide so that you don't make the same mistakes I did during the project I was developing. I tried to put as many details as possible in the step-by-step instructions and the reasons behind them. &lt;/p&gt;

&lt;p&gt;These instructions can be replicated in other projects, even if they don't follow the same technology, but if their concepts are similar, it's possible. If you don't apply them immediately, at least I hope you've learned something from what I demonstrated in this article. &lt;/p&gt;

&lt;p&gt;Any positive criticism that can enhance this article is welcome! Share with other people who need this content! &lt;/p&gt;

&lt;p&gt;Thank you for your attention.&lt;/p&gt;

</description>
      <category>graphql</category>
      <category>database</category>
      <category>hasura</category>
      <category>migrations</category>
    </item>
    <item>
      <title>Reduzindo as chances de errar um squash de migrações no Hasura</title>
      <dc:creator>Fernando Karchiloff</dc:creator>
      <pubDate>Wed, 15 Dec 2021 15:55:59 +0000</pubDate>
      <link>https://forem.com/ferkarchiloff/reduzindo-as-chances-de-errar-um-squash-de-migracoes-no-hasura-3c23</link>
      <guid>https://forem.com/ferkarchiloff/reduzindo-as-chances-de-errar-um-squash-de-migracoes-no-hasura-3c23</guid>
      <description>&lt;h1&gt;
  
  
  Sumário
&lt;/h1&gt;

&lt;ol&gt;
&lt;li&gt;Versão das tecnologias&lt;/li&gt;
&lt;li&gt;Requisitos mínimos de conhecimento para entender o artigo&lt;/li&gt;
&lt;li&gt;Por quê deste artigo&lt;/li&gt;
&lt;li&gt;Para os apressados&lt;/li&gt;
&lt;li&gt;Exemplo de base de dados&lt;/li&gt;
&lt;li&gt;Processo de fazer um squash&lt;/li&gt;
&lt;li&gt;Conclusão&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Versão das tecnologias
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Hasura v2.0.9&lt;/li&gt;
&lt;li&gt;Hasura CLI v2.0.9&lt;/li&gt;
&lt;li&gt;PostgreSQL 12&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Requisitos mínimos de conhecimento para entender o artigo
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Entender de comandos SQL&lt;/li&gt;
&lt;li&gt;Como migrações funcionam&lt;/li&gt;
&lt;li&gt;Como &lt;a href="https://hasura.io/docs/latest/graphql/core/getting-started/index.html#getting-started" rel="noopener noreferrer"&gt;Hasura GraphQL Engine&lt;/a&gt; funciona&lt;/li&gt;
&lt;li&gt;Como &lt;a href="https://git-scm.com/" rel="noopener noreferrer"&gt;Git&lt;/a&gt; funciona&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Por quê deste artigo
&lt;/h2&gt;

&lt;p&gt;Durante o desenvolvimento de um dos projetos de uma empresa de &lt;em&gt;e-commerce&lt;/em&gt;, tivemos uma tarefa que seria necessário mudar a estrutura do banco de dados, esta alteração mexeria com diversas tabelas e colunas para que o objetivo da tarefa fosse concluído.&lt;/p&gt;

&lt;p&gt;Como o Hasura GraphQL Engine oferece uma interface para fazer as mudanças na estrutura do banco de dados, modifiquei por meio desta e executei as queries manuais que se mostraram necessárias, todas essas modificações criavam migrações no repositório do projeto, assim como esperado para um projeto com migrações habilitadas no Hasura.&lt;/p&gt;

&lt;p&gt;Após as modificações, era notável a quantidade de pastas com modificações que foram sendo gravadas no formato de migrações, decidi então usar o comando para comprimir todas elas em um único arquivo, o que seria mais legível, e minha falha se concretizou no momento que executei o comando. &lt;/p&gt;

&lt;p&gt;Sem ter feito validações básicas antes, executei o comando e excluí as migrações anteriores. E assim passei mais de um dia tentando corrigir o erro que cometi por não fazer uma lista de verificação básica antes de usar o comando. Como evitar isso? Vou te explicar no decorrer do artigo.&lt;/p&gt;

&lt;h2&gt;
  
  
  Para os apressados
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Faça as suas modificações usando migrações.&lt;/li&gt;
&lt;li&gt;Usando Git ou outro versionador, faça um commit para salvar as migrações.&lt;/li&gt;
&lt;li&gt;Garanta que os arquivos de &lt;code&gt;up.sql&lt;/code&gt; e &lt;code&gt;down.sql&lt;/code&gt; executam como deveriam usando &lt;code&gt;hasura migrate apply&lt;/code&gt; e &lt;code&gt;hasura migrate apply --down &amp;lt;N&amp;gt;&lt;/code&gt;. Correções manuais (caso erros aconteçam), faça pela aba &lt;code&gt;SQL&lt;/code&gt; sem usar migrações.&lt;/li&gt;
&lt;li&gt;Salve as migrações completas no versionador.&lt;/li&gt;
&lt;li&gt;Use o comando &lt;code&gt;hasura migrate squash --from &amp;lt;num_migracao&amp;gt; --name &amp;lt;name&amp;gt;&lt;/code&gt; para executar o &lt;em&gt;squash&lt;/em&gt;, remova as migrações anteriores (pois você já salvou no versionador).&lt;/li&gt;
&lt;li&gt;Marque a migração que foi criada como preenchida no banco, usando &lt;code&gt;hasura migrate apply --skip-execution&lt;/code&gt; (se as que serão removidas não haviam sido aplicadas, não use a &lt;em&gt;flag&lt;/em&gt;).&lt;/li&gt;
&lt;li&gt;Use novamente o &lt;code&gt;hasura migrate apply --down &amp;lt;N&amp;gt;&lt;/code&gt; para retirar, e sem a &lt;em&gt;flag&lt;/em&gt; para colocar as migrações, garantindo que sua migração funciona.&lt;/li&gt;
&lt;li&gt;Grave as alterações no versionador.&lt;/li&gt;
&lt;li&gt;(Opcional) Faça otimizações de comandos SQL se achar necessário, exemplo: remover &lt;code&gt;ALTER TABLE&lt;/code&gt; caso exista um &lt;code&gt;DROP TABLE&lt;/code&gt; para uma tabela (sem perda de dados).&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Exemplo de base de dados
&lt;/h2&gt;

&lt;p&gt;Para demonstrar como fazer um &lt;em&gt;squash&lt;/em&gt; corretamente, irei utilizar uma base de dados de exemplo simples com uma única tabela, mas no caso real você pode ter diversas operações entre &lt;em&gt;N&lt;/em&gt; tabelas, o que pode tornar o &lt;em&gt;squash&lt;/em&gt; maior e mais complexo.&lt;/p&gt;

&lt;p&gt;A nossa base contém a tabela &lt;code&gt;students&lt;/code&gt; definida por meio desta estrutura:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="nv"&gt;"public"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;"students"&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nv"&gt;"id"&lt;/span&gt; &lt;span class="nb"&gt;serial&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nv"&gt;"name"&lt;/span&gt; &lt;span class="nb"&gt;Text&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nv"&gt;"score"&lt;/span&gt; &lt;span class="nb"&gt;text&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ela foi criada depois que já executamos a conexão com a nossa base de dados criada no PostgreSQL, desativamos o console e iniciamos as migrações no projeto. Você pode ver mais detalhes de como ativar migrações nesta &lt;a href="https://hasura.io/docs/latest/graphql/core/migrations/migrations-setup.html" rel="noopener noreferrer"&gt;seção&lt;/a&gt; de &lt;em&gt;Migrations &amp;amp; Metadata (CI/CD)&lt;/em&gt; na documentação do &lt;em&gt;Hasura GraphQL Engine&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Digamos então que esta tabela foi preenchida com alguns dados de estudantes:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg1goo3fgozuc3tasrzz1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg1goo3fgozuc3tasrzz1.png" alt="Tabela com três colunas chamadas: " id=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;No meio do caminho, percebemos que os dados das notas localizados na coluna &lt;code&gt;score&lt;/code&gt;, não poderiam ser textos, pois gostaríamos de fazer algumas aritméticas com eles. Entretanto, não podemos mudar estes dados caso estejam em uso no ambiente de produção! (Suponha que você tenha milhares de dados importantes e não pode perdê-los)&lt;/p&gt;

&lt;p&gt;O que fazer então? No ambiente de desenvolvimento, iremos &lt;strong&gt;criar uma coluna&lt;/strong&gt; para acomodar esses dados, vamos nomeá-la &lt;code&gt;score_decimal&lt;/code&gt;, pois representa a nota em número decimal permitindo operações aritméticas. Vá até à aba &lt;em&gt;Modify&lt;/em&gt; da tabela &lt;code&gt;students&lt;/code&gt; e clique em &lt;em&gt;Add new column&lt;/em&gt;. Vamos definir como uma coluna &lt;code&gt;Numeric&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6iop7eaqomy9s2yt4u2o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6iop7eaqomy9s2yt4u2o.png" alt="Aba de Modify selecionada e com opção de adicionar nova coluna aparecendo com dados preenchidos"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Uma vez criada a nova coluna, podemos fazer a migração dos dados da coluna &lt;code&gt;score&lt;/code&gt; para &lt;code&gt;score_decimal&lt;/code&gt;. Para isso ser possível, vamos usar a seção de &lt;code&gt;SQL&lt;/code&gt; que fica logo abaixo das tabelas da nossa base de dados.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7euulbm2lsd9aq5v9gm2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7euulbm2lsd9aq5v9gm2.png" alt="Bancos de dados sendo exibidos na aba de cima e logo abaixo a aba de SQL"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Nessa aba você pode rodar código SQL diretamente contra o banco de dados selecionado, podendo marcar estas consultas como migrações ou não. Dependendo do código, o Hasura talvez seja inteligente para identificar ser uma alteração estrutural ou de dados e marque como migração automaticamente, então sempre preste atenção antes de rodar a consulta para ver se a caixa de "&lt;em&gt;This is a migration&lt;/em&gt;" está habilitada.&lt;/p&gt;

&lt;p&gt;Colocando a consulta que converte as notas no campo de texto, podemos rodar sem adicionar como migração com intenção de verificar se a consulta está sendo executada como descrita. Após a verificação, podemos ativar a caixa de migração e escrever um nome para ela, usei um nome descritivo &lt;code&gt;cast_students_score_to_decimal_migration&lt;/code&gt;.&lt;br&gt;
Esta é a consulta feita para converter os dados:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="n"&gt;students&lt;/span&gt;
&lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;score_decimal&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;CAST&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="nb"&gt;DECIMAL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;students&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;students&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7izhheuev7kw4gpd6ugo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7izhheuev7kw4gpd6ugo.png" alt="Aba SQL com consulta preenchida no campo de texto e função de migração ativada"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;OBSERVAÇÃO: sempre tome cuidado para fazer alterações estruturais que mudam categorias de campos, então faça por partes e vá atualizando a camada de visualização (front-end), caso sejam utilizadas, para mudar o novo tipo sem quebrar a aplicação para os clientes.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Após rodar a atualização dos dados, podemos renomear as colunas e deletar a antiga. O nome usado para migração foi &lt;code&gt;rename_columns_and_remove_old_migration&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;ALTER&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;students&lt;/span&gt; &lt;span class="k"&gt;RENAME&lt;/span&gt; &lt;span class="k"&gt;COLUMN&lt;/span&gt; &lt;span class="nv"&gt;"score"&lt;/span&gt; &lt;span class="k"&gt;TO&lt;/span&gt; &lt;span class="nv"&gt;"score_text"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;ALTER&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;students&lt;/span&gt; &lt;span class="k"&gt;RENAME&lt;/span&gt; &lt;span class="k"&gt;COLUMN&lt;/span&gt; &lt;span class="nv"&gt;"score_decimal"&lt;/span&gt; &lt;span class="k"&gt;TO&lt;/span&gt; &lt;span class="nv"&gt;"score"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;ALTER&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;students&lt;/span&gt; &lt;span class="k"&gt;DROP&lt;/span&gt; &lt;span class="k"&gt;COLUMN&lt;/span&gt; &lt;span class="nv"&gt;"score_text"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm85kjzac5sndhxbljb4k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm85kjzac5sndhxbljb4k.png" alt="Aba SQL com consulta preenchida no campo de texto e função de migração ativada"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Com isso, finalizamos nossa modificação para executarmos nossas operações aritméticas, mas acabamos com algumas migrações separadas que podem ser unidas através de uma operação de &lt;code&gt;squash&lt;/code&gt;, pois podem ser executadas todas juntas.&lt;/p&gt;

&lt;h2&gt;
  
  
  Processo de fazer um squash
&lt;/h2&gt;

&lt;p&gt;Para que o processo de &lt;em&gt;squash&lt;/em&gt; das migrações ocorra "corretamente" (sempre pode ocorrer algum erro inesperado no meio do processo), precisamos garantir que algumas etapas sejam seguidas. Vou listar algumas delas para evitar erros desse processo.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Gravar as migrações feitas no repositório&lt;/li&gt;
&lt;li&gt;Garantir que as migrações podem ser feitas e desfeitas sem erros&lt;/li&gt;
&lt;li&gt;Gravar as migrações completas&lt;/li&gt;
&lt;li&gt;Fazer o &lt;em&gt;squash&lt;/em&gt; das migrações&lt;/li&gt;
&lt;li&gt;Marcar a migração como executada&lt;/li&gt;
&lt;li&gt;Grave as alterações&lt;/li&gt;
&lt;li&gt;(Opcional) Modifique a migração comprimida como desejar (e grave as alterações)&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  1. Gravar as migrações feitas
&lt;/h3&gt;

&lt;p&gt;Para mantermos controle das nossas migrações e não perdermos o progresso feito, gravamos as alterações em um commit do versionador, podemos então prosseguir em alterá-las sem risco de perder o que já fizemos, esse foi um dos erros que cometi anteriormente, não ter salvo no versionador.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Garanta que as migrações podem ser feitas e desfeitas sem erros
&lt;/h3&gt;

&lt;p&gt;Com as migrações salvas no repositório, podemos começar a modificação das que possuem arquivos &lt;code&gt;down.sql&lt;/code&gt; incompletos. Muitas das alterações que executamos no banco de dados, nem sempre refletem nos arquivos por serem modificações complexas, como a renomeação das colunas e deleção de coluna na mesma migração. Por exemplo, a última migração, o arquivo &lt;code&gt;down.sql&lt;/code&gt; foi preenchido desta forma:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Could not auto-generate a down migration.&lt;/span&gt;
&lt;span class="c1"&gt;-- Please write an appropriate down migration for the SQL below:&lt;/span&gt;
&lt;span class="c1"&gt;-- ALTER TABLE students RENAME COLUMN "score" TO "score_text";&lt;/span&gt;
&lt;span class="c1"&gt;-- ALTER TABLE students RENAME COLUMN "score_decimal" TO "score";&lt;/span&gt;
&lt;span class="c1"&gt;-- ALTER TABLE students DROP COLUMN "score_text";&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Para que a migração funcione na volta, ou seja, remover as mudanças, vamos inverter os comandos feitos no &lt;code&gt;up.sql&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;ALTER&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;students&lt;/span&gt; &lt;span class="k"&gt;ADD&lt;/span&gt; &lt;span class="k"&gt;COLUMN&lt;/span&gt; &lt;span class="nv"&gt;"score_text"&lt;/span&gt; &lt;span class="nb"&gt;text&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;ALTER&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;students&lt;/span&gt; &lt;span class="k"&gt;RENAME&lt;/span&gt; &lt;span class="k"&gt;COLUMN&lt;/span&gt; &lt;span class="nv"&gt;"score"&lt;/span&gt; &lt;span class="k"&gt;TO&lt;/span&gt; &lt;span class="nv"&gt;"score_decimal"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;ALTER&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;students&lt;/span&gt; &lt;span class="k"&gt;RENAME&lt;/span&gt; &lt;span class="k"&gt;COLUMN&lt;/span&gt; &lt;span class="nv"&gt;"score_text"&lt;/span&gt; &lt;span class="k"&gt;TO&lt;/span&gt; &lt;span class="nv"&gt;"score"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Faremos o mesmo com a migração que cria a nova coluna e inverteremos o comando.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;ALTER&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="nv"&gt;"public"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;"students"&lt;/span&gt; &lt;span class="k"&gt;DROP&lt;/span&gt; &lt;span class="k"&gt;COLUMN&lt;/span&gt; &lt;span class="nv"&gt;"score_decimal"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Com isso, podemos usar as &lt;em&gt;flags&lt;/em&gt; de &lt;code&gt;--up&lt;/code&gt; e &lt;code&gt;--down&lt;/code&gt; do &lt;code&gt;hasura migrate apply&lt;/code&gt;. O comando altera o banco de dados conforme os &lt;code&gt;.sql&lt;/code&gt; definidos nas migrações. Se você relacionar os arquivos aos seus respectivos comandos, fará mais sentido, o comando que usa &lt;code&gt;--down&lt;/code&gt; vai remover as alterações de migrações já aplicadas, enquanto o &lt;code&gt;--up&lt;/code&gt; irá aplicá-las (o &lt;code&gt;--up&lt;/code&gt; é aplicado por padrão se não for definido). Para remover somente algumas, use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;hasura migrate apply &lt;span class="nt"&gt;--down&lt;/span&gt; &amp;lt;N&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No comando, &lt;em&gt;N&lt;/em&gt; é a quantidade de migrações que serão removidas. Use &lt;code&gt;hasura migrate apply --help&lt;/code&gt; para mais detalhes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Observação: se você executou alguma migração e ela falhou, caso tenha mais de um comando SQL no mesmo arquivo, tente corrigir pela aba &lt;code&gt;SQL&lt;/code&gt; (sem fazer uma nova), corrigi-la e tentar novamente.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Grave as migrações completas
&lt;/h3&gt;

&lt;p&gt;Dado que você testou suas migrações, e elas estão funcionando, grave novamente em um commit, agora com as migrações completas.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Fazer o &lt;em&gt;squash&lt;/em&gt; das migrações
&lt;/h3&gt;

&lt;p&gt;Com todas as migrações completas e funcionando ida e volta, podemos agora fazer o &lt;em&gt;squash&lt;/em&gt; delas, ou seja, comprimi-las em uma única só migração, para isso, vamos rodar o comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;hasura migrate squash &lt;span class="nt"&gt;--from&lt;/span&gt; &amp;lt;num_migracao&amp;gt; &lt;span class="nt"&gt;--name&lt;/span&gt; &amp;lt;name&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ele executa a compressão dos arquivos das migrações para nós. No meu caso, farei dessa forma:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;hasura migrate squash &lt;span class="nt"&gt;--from&lt;/span&gt; 1638852925395 &lt;span class="nt"&gt;--name&lt;/span&gt; &lt;span class="s2"&gt;"changing_column_type"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Este comando irá a partir da migração de prefixo &lt;code&gt;1638852925395&lt;/code&gt; juntar todas em uma única, de nome &lt;em&gt;"changing_column_type"&lt;/em&gt;. Recomendo você deletar as migrações anteriores pois já estão salvas no repositório.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Marcar a migração como executada
&lt;/h3&gt;

&lt;p&gt;Assim que criamos a nossa nova migração comprimida como resultado da operação, &lt;strong&gt;caso as migrações anteriores não estivessem aplicadas no banco de dados&lt;/strong&gt;, vamos rodar o comando para marcar como se a migração que acabamos de gerar, já tivesse sido aplicada:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;hasura migrate apply &lt;span class="nt"&gt;--skip-execution&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Lembrando que este comando só deve ser executado se efetivamente aplicamos as alterações das outras migrações no banco de dados, caso contrário, rode o comando sem a &lt;em&gt;flag&lt;/em&gt; &lt;code&gt;--skip-execution&lt;/code&gt; para aplicar normalmente.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Grave as alterações
&lt;/h3&gt;

&lt;p&gt;Feito isso, grave novamente as alterações na versão de controle do repositório para não perder suas alterações.&lt;/p&gt;

&lt;h3&gt;
  
  
  7. (Opcional) Modifique a migração comprimida como desejar (e grave as alterações)
&lt;/h3&gt;

&lt;p&gt;Se a sua migração possui muitos comandos, avalie o arquivo e verifique se, dependendo das alterações feitas, você pode simplificar o código SQL executado. Por exemplo, você cria uma tabela, e depois em outra migração adiciona uma coluna, caso você não tenha adicionado nenhum dado no meio do caminho, ou não foi para produção ainda, coloque diretamente a coluna na criação da tabela, o que simplificará o código.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;Espero que estas instruções sirvam de guia para que não cometa os mesmos erros que eu durante o projeto que estava desenvolvendo. Tentei colocar o máximo de detalhes no passo a passo e seus motivos. &lt;/p&gt;

&lt;p&gt;Essas instruções podem ser replicadas em outros projetos, mesmo que não sigam a mesma tecnologia, mas se seus conceitos forem parecidos, é possível. Caso você não aplique imediatamente, ao menos espero que tenha aprendido algo com o que demonstrei neste artigo.&lt;/p&gt;

&lt;p&gt;Qualquer crítica positiva que possa incrementar este artigo é bem-vinda! Compartilhe com outras pessoas que precisam deste conteúdo!&lt;/p&gt;

&lt;p&gt;Obrigado por sua atenção.&lt;/p&gt;

</description>
      <category>graphql</category>
      <category>database</category>
      <category>hasura</category>
      <category>migrations</category>
    </item>
  </channel>
</rss>
