<?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: Kelson V</title>
    <description>The latest articles on DEV Community by Kelson V (@kelson_v_f7c45489ea4931ea).</description>
    <link>https://dev.to/kelson_v_f7c45489ea4931ea</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%2F3733045%2F39f58f0b-31f6-4f49-980b-6c47ccdfc6a3.png</url>
      <title>DEV Community: Kelson V</title>
      <link>https://dev.to/kelson_v_f7c45489ea4931ea</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/kelson_v_f7c45489ea4931ea"/>
    <language>en</language>
    <item>
      <title>Moving Data from SQL Server to Postgres with NiFi</title>
      <dc:creator>Kelson V</dc:creator>
      <pubDate>Mon, 26 Jan 2026 15:05:02 +0000</pubDate>
      <link>https://dev.to/kelson_v_f7c45489ea4931ea/moving-data-from-sql-server-to-postgres-with-nifi-1oid</link>
      <guid>https://dev.to/kelson_v_f7c45489ea4931ea/moving-data-from-sql-server-to-postgres-with-nifi-1oid</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Learn how to build a containerized ETL pipeline using Apache NiFi to move data from SQL Server to PostgreSQL, featuring fixes for JDBC driver setup and timestamp type mismatches.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I recently set up a pipeline to move sales records from SQL Server to PostgreSQL using NiFi and Docker.&lt;/p&gt;

&lt;p&gt;It’s a standard task, but there are a few manual steps and annoying errors that I had to fix. Here is exactly how I did it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why move the data?
&lt;/h2&gt;

&lt;p&gt;Basically, you don't want to run heavy analytics on your main SQL Server while people are trying to use it. Moving the data to a separate Postgres database keeps things fast for everyone.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Setup
&lt;/h2&gt;

&lt;p&gt;I ran everything in Docker so I didn't have to install stuff on my actual computer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;SQL Server: Where the data starts.&lt;/li&gt;
&lt;li&gt;Postgres: Where the data ends up.&lt;/li&gt;
&lt;li&gt;NiFi: The tool that moves the data.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step 1: Getting the Drivers Ready
&lt;/h2&gt;

&lt;p&gt;NiFi is a Java app and doesn't know how to talk to these databases by default. You have to manually give it the JDBC driver files (the .jar files).&lt;/p&gt;

&lt;p&gt;Download the drivers here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;SQL Server: &lt;a href="https://learn.microsoft.com/en-us/sql/connect/jdbc/download-microsoft-jdbc-driver-for-sql-server" rel="noopener noreferrer"&gt;https://learn.microsoft.com/en-us/sql/connect/jdbc/download-microsoft-jdbc-driver-for-sql-server&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Postgres: &lt;a href="https://jdbc.postgresql.org/download/" rel="noopener noreferrer"&gt;https://jdbc.postgresql.org/download/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Since everything is in Docker, I used these commands to "push" the drivers into the NiFi container:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker cp C:\drivers\mssql-jdbc-13.2.1.jre11.jar nifi-orchestrator:/opt/nifi/nifi-current/lib/
docker cp C:\drivers\postgresql-42.7.9.jar nifi-orchestrator:/opt/nifi/nifi-current/lib/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note: You have to restart the NiFi container after this or it won't see the drivers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Setting up the NiFi Flow
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F0vydodeu7lbhpn3v0kfh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F0vydodeu7lbhpn3v0kfh.png" alt=" " width="800" height="295"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I used three main boxes (processors) to get this done:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;GenerateTableFetch: This checks SQL Server for new rows. I set the Maximum-value Column to id. This is important because it tells NiFi: "Only grab rows with an ID higher than the last one we moved." No duplicates.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;ExecuteSQL: This actually pulls the data.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;PutDatabaseRecord: This sends the data into the Postgres table (stg_sales).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step 3: Fixing the Timestamp Error
&lt;/h2&gt;

&lt;p&gt;This was the only real problem I hit. Postgres is very picky about dates. By default, NiFi sends dates as plain text, which makes Postgres crash with a character varying error.&lt;/p&gt;

&lt;p&gt;The Fix: Go to the ExecuteSQL properties and set Use Avro Logical Types to true. This makes sure the date stays a "date" so Postgres accepts it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: How to Reset for Testing
&lt;/h2&gt;

&lt;p&gt;If you want to test the flow again with the same data, NiFi won't move it because it "remembers" the last ID.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Stop the processor.&lt;/li&gt;
&lt;li&gt;Right-click → View State.&lt;/li&gt;
&lt;li&gt;Click Clear State.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Also, don't leave the Run Schedule at 0 sec. Set it to 10 sec so it doesn't max out your CPU.&lt;/p&gt;

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

&lt;p&gt;Once everything was green, I checked DBeaver and the data was all there. It’s a simple setup once you get the drivers and the timestamp setting right.&lt;/p&gt;

</description>
      <category>dataengineering</category>
      <category>docker</category>
      <category>apachenifi</category>
      <category>sql</category>
    </item>
  </channel>
</rss>
