<?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: Narayan</title>
    <description>The latest articles on DEV Community by Narayan (@narayanpromax).</description>
    <link>https://dev.to/narayanpromax</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%2F388322%2F39739948-46ff-49cb-923d-aa7334ba3693.jpg</url>
      <title>DEV Community: Narayan</title>
      <link>https://dev.to/narayanpromax</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/narayanpromax"/>
    <language>en</language>
    <item>
      <title>MySQL to Postgres Migration using Docker with pgloader for Hasura</title>
      <dc:creator>Narayan</dc:creator>
      <pubDate>Wed, 20 May 2020 10:12:43 +0000</pubDate>
      <link>https://dev.to/narayanpromax/mysql-to-postgres-migration-using-docker-with-pgloader-for-hasura-mg</link>
      <guid>https://dev.to/narayanpromax/mysql-to-postgres-migration-using-docker-with-pgloader-for-hasura-mg</guid>
      <description>&lt;p&gt;Follow me on &lt;a href="https://twitter.com/@narayandreamer" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;, happy to help or take suggestions from you /Narayan&lt;/p&gt;

&lt;p&gt;This is my first article so please ignore my mistakes.&lt;/p&gt;

&lt;p&gt;TLDR; This article is about converting a MySQL database to Postgres using pgloader with Docker. If you want code directly then skip to end. &lt;/p&gt;

&lt;p&gt;I recently made a decision to use #Hasura for backend on one of my products. Reason REST sucks. Although REST is still powering majority of internet but once you taste the blood, there's no going back. Same thing happened with SOAP when REST came. Problem with REST is development time and updating. #GraphQL was the answer for me. But since #Hasura only supports Postgres as of now I needed to migrate my MySQL to Postgres.&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%2Fi%2Fhzckskf2erp2o2hbfthe.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%2Fi%2Fhzckskf2erp2o2hbfthe.png" alt="Hasura"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I asked Hasura team about MySQL Support and got a reply that its under development and will come out soon, possibly 2 months from now. The thing about open source software is that we want it to support our ecosystem, so i was literally asking every few days to &lt;a href="https://twitter.com/@rajoshighosh" rel="noopener noreferrer"&gt;Rajoshi&lt;/a&gt; about MySQL support landing. But any new thing takes time. They have to properly test everything and then initial beta comes out and then final release. We become greedy and I'm not gonna lie I too became greedy, the sooner it comes out the better for obvious reasons.&lt;/p&gt;

&lt;h1&gt;
  
  
  Setup
&lt;/h1&gt;

&lt;p&gt;Then 1 day I thought of migrating my existing MySQL setup to Postgres. Since the product is not in production, now is a good time to migrate. I started reading about it and came to know about this tool called pgloader. I was happy i got the tool. Below is my experience with different local setups for using pgloader&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;❌ &lt;strong&gt;Standalone MySQL and PostgreSQL and pgloader:&lt;/strong&gt; In this setup MySQL, PostgreSQL i installed from their official site on MacOSX and pgloader with homebrew &lt;code&gt;brew install pgloader&lt;/code&gt;. Didn't work out for me&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;❌ &lt;strong&gt;Docker MySQL and PostgreSQL and Standalone pgloader:&lt;/strong&gt; In this setup MySQL, PostgreSQL were installed via Docker and pgloader with homebrew &lt;code&gt;brew install pgloader&lt;/code&gt;. Didn't work out for me&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;✅ &lt;strong&gt;Docker MySQL and PostgreSQL and pgloader:&lt;/strong&gt; In this setup MySQL, PostgreSQL and pgloader were all installed via Docker and it worked. Reaching this stage i found out that problem was pgloader installed via Homebrew. When i ran pgloader via Docker then Standalone MySQL and Standalone PostgreSQL also worked.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Learning&lt;/em&gt; : Always use Docker for such tasks (or generally too) as we can isolate environment and dependencies. A &lt;strong&gt;Big Shoutout&lt;/strong&gt; to &lt;a href="https://twitter.com/GavinRayDev" rel="noopener noreferrer"&gt;GavinRay&lt;/a&gt; from &lt;a href="https://twitter.com/HasuraHQ" rel="noopener noreferrer"&gt;Hasura&lt;/a&gt; who helped me reach 3rd setup and prevented me from going bald with all my hair i was pulling out of frustration with 1st and 2nd setup.&lt;/p&gt;

&lt;h1&gt;
  
  
  Let's get started
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;Install &lt;a href="https://www.docker.com/products/docker-desktop" rel="noopener noreferrer"&gt;Docker&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Take MySQL dump from your MySQL Client like phpmyadmin, Sequel Pro etc in .sql format&lt;/li&gt;
&lt;li&gt;Now we need a docker-compose.yaml for our services. We require 3 services (MySQL, Postgres and pgloader)
```yaml
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;version: '3.6'&lt;br&gt;
services:&lt;br&gt;
  postgres:&lt;br&gt;
    build: postgres-with-pgloader&lt;br&gt;
    container_name: postgres-db&lt;br&gt;
    ports:&lt;br&gt;
      - '5431:5432'&lt;br&gt;
    restart: always&lt;br&gt;
    volumes:&lt;br&gt;
      - db_data:/var/lib/postgresql/data&lt;br&gt;
    environment:&lt;br&gt;
      POSTGRES_PASSWORD: root&lt;/p&gt;

&lt;p&gt;mysql:&lt;br&gt;
    image: mysql:5.7&lt;br&gt;
    container_name: mysql-db&lt;br&gt;
    ports:&lt;br&gt;
      - '3307:3306'&lt;br&gt;
    volumes:&lt;br&gt;
      - /var/lib/mysql&lt;br&gt;
      - ./migrations:/docker-entrypoint-initdb.d&lt;br&gt;
    environment:&lt;br&gt;
      MYSQL_DATABASE: database&lt;br&gt;
      MYSQL_USER: user&lt;br&gt;
      MYSQL_PASSWORD: password&lt;br&gt;
      MYSQL_ROOT_PASSWORD: root_password&lt;/p&gt;

&lt;p&gt;volumes:&lt;br&gt;
  db_data:&lt;/p&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- As seen in docker-compose.yaml file, postgres is 1 service which has postgres running with pgloader. Since it has build parameter refers to `postgres-with-pgloader` defined we need to have a `Dockerfile` inside that folder like `postgres-with-pgloader/Dockerfile` with following content
```yaml


FROM postgres:latest
RUN apt-get update
RUN apt-get install -y wget sudo pgloader


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

&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;MySQL is another service where we don't require build parameter but we will directly build from image. But since we will use dump taken in 2nd step we need to initialize MySQL service with that dump via migrations. So we have specified &lt;code&gt;- ./migrations:/docker-entrypoint-initdb.d&lt;/code&gt;. This will take any sql in migrations folder and make db &lt;code&gt;MYSQL_DATABASE: database&lt;/code&gt; from that dump. Pretty cool ha! 🤓&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If you see ports for Postgres and MySQL have been mapped externally to 5431 and 3307 respectively. This is to avoid clash with any existing service running standalone of these Databases. It's better to be safe.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Now in root make a shell script &lt;code&gt;pgloader_migrate.sh&lt;/code&gt; like below&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

docker-compose &lt;span class="nb"&gt;exec &lt;/span&gt;postgres pgloader &lt;span class="se"&gt;\&lt;/span&gt;
mysql://user:password@mysql:3306/database &lt;span class="se"&gt;\&lt;/span&gt;
postgresql://postgres:root@localhost:5432/postgres


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

&lt;/div&gt;
&lt;p&gt;Since pgloader is running inside and that too inside postgres service, it can reference postgres as localhost, but it has to connect to MySQL via &lt;code&gt;mysql&lt;/code&gt; service connector. Again ports will remain internal of docker as pgloader is running internally.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Folder structure should look like below&lt;/li&gt;
&lt;/ul&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%2Fi.imgur.com%2FtooHQs7.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%2Fi.imgur.com%2FtooHQs7.png" alt="mysql2pgsql-docker-folder"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Now run &lt;code&gt;docker-compose up -d&lt;/code&gt; in root to let Docker do it's magic. After both containers are online run &lt;code&gt;./pgloader_migrate.sh&lt;/code&gt; then you should get a screen like this &lt;/li&gt;
&lt;/ul&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%2Fi.imgur.com%2F7xZpf3h.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%2Fi.imgur.com%2F7xZpf3h.png" alt="mysql2pgsql-docker-shell"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You can connect to postgres with pgAdmin, phppgadmin and see if all is well.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Do give a like ♥️ if this article helped you&lt;/p&gt;
&lt;h1&gt;
  
  
  Thanks
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://hasura.io" rel="noopener noreferrer"&gt;Hasura&lt;/a&gt;&lt;br&gt;
&lt;a href="https://twitter.com/GavinRayDev" rel="noopener noreferrer"&gt;GavinRay&lt;/a&gt;&lt;br&gt;
&lt;a href="https://pgloader.io/" rel="noopener noreferrer"&gt;pgloader&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;
  
  
  Source Code
&lt;/h1&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&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%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/narayanpromax" rel="noopener noreferrer"&gt;
        narayanpromax
      &lt;/a&gt; / &lt;a href="https://github.com/narayanpromax/mysql2pgsql-docker" rel="noopener noreferrer"&gt;
        mysql2pgsql-docker
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      MySQL to PostgreSQL with pgloader and Docker
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;


</description>
      <category>mysql</category>
      <category>postgres</category>
      <category>hasura</category>
      <category>docker</category>
    </item>
  </channel>
</rss>
