<?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>DEV Community: Joaquin Orozco</title>
    <description>The latest articles on DEV Community by Joaquin Orozco (@jog16889).</description>
    <link>https://dev.to/jog16889</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4215596%2F537fd470-81a8-4488-aaf2-2e8328de9764.png</url>
      <title>DEV Community: Joaquin Orozco</title>
      <link>https://dev.to/jog16889</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jog16889"/>
    <language>en</language>
    <item>
      <title>Catch risky SQL migrations in pull requests before they lock production</title>
      <dc:creator>Joaquin Orozco</dc:creator>
      <pubDate>Thu, 29 Oct 2026 15:37:54 +0000</pubDate>
      <link>https://dev.to/jog16889/catch-risky-sql-migrations-in-pull-requests-before-they-lock-production-2hgd</link>
      <guid>https://dev.to/jog16889/catch-risky-sql-migrations-in-pull-requests-before-they-lock-production-2hgd</guid>
      <description>&lt;p&gt;Most migration incidents aren't exotic: a &lt;code&gt;DROP COLUMN&lt;/code&gt; that an old app instance still reads, an&lt;br&gt;
&lt;code&gt;ALTER COLUMN ... SET NOT NULL&lt;/code&gt; that scans a 200-million-row table, a &lt;code&gt;CREATE INDEX&lt;/code&gt; without&lt;br&gt;
&lt;code&gt;CONCURRENTLY&lt;/code&gt; that blocks writes for minutes, an &lt;code&gt;UPDATE&lt;/code&gt; that forgot its &lt;code&gt;WHERE&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;I build &lt;strong&gt;MigrationGuard&lt;/strong&gt;, a JetBrains plugin that reviews migration SQL as you write it, and I've just&lt;br&gt;
released a free &lt;strong&gt;GitHub Action&lt;/strong&gt; that runs the same checks on every pull request.&lt;/p&gt;

&lt;h2&gt;
  
  
  Add it to a repository
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Migrations&lt;/span&gt;
&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;pull_request&lt;/span&gt;
&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;migrationguard&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v5&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;fetch-depth&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;jog16889/migrationguard-action@v1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It only looks at the &lt;code&gt;.sql&lt;/code&gt; files changed in the pull request, annotates the risky lines, explains a safer&lt;br&gt;
approach for each one and fails the job on high or critical risks. Nothing leaves the runner: no database&lt;br&gt;
connection, no SQL uploaded.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it flags (free)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;DROP TABLE&lt;/code&gt; / &lt;code&gt;DROP COLUMN&lt;/code&gt; and &lt;code&gt;TRUNCATE&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;UPDATE&lt;/code&gt; / &lt;code&gt;DELETE&lt;/code&gt; without &lt;code&gt;WHERE&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Column type changes that rewrite or truncate data&lt;/li&gt;
&lt;li&gt;PostgreSQL &lt;code&gt;CREATE INDEX&lt;/code&gt; without &lt;code&gt;CONCURRENTLY&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The dialect (PostgreSQL or MySQL) is inferred from the file, your Spring/Flyway/Liquibase config,&lt;br&gt;
docker-compose or your JDBC driver dependency; you can pin it in &lt;code&gt;.migrationguard.yml&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  In the IDE
&lt;/h2&gt;

&lt;p&gt;The plugin (IntelliJ IDEA Ultimate, DataGrip) shows the same findings while you type. Its Pro edition adds&lt;br&gt;
rolling-deploy and locking rules (unsafe &lt;code&gt;NOT NULL&lt;/code&gt;, volatile defaults, renames, constraint changes, MySQL&lt;br&gt;
table rebuilds), a whole-project audit and an audit of only the migrations changed in your branch. There's a&lt;br&gt;
7-day free trial.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Action: &lt;a href="https://github.com/jog16889/migrationguard-action" rel="noopener noreferrer"&gt;https://github.com/jog16889/migrationguard-action&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Plugin: &lt;a href="https://plugins.jetbrains.com/plugin/34107-migrationguard" rel="noopener noreferrer"&gt;https://plugins.jetbrains.com/plugin/34107-migrationguard&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;40-second demo: &lt;a href="https://youtu.be/hWC3Dp3_zIs" rel="noopener noreferrer"&gt;https://youtu.be/hWC3Dp3_zIs&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Feedback welcome — especially false positives from real migrations.&lt;/p&gt;

</description>
      <category>postgres</category>
      <category>database</category>
      <category>devops</category>
      <category>github</category>
    </item>
  </channel>
</rss>
