Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

Sorry, you do not have permission to ask a question, You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please type your username.

Please type your E-Mail.

Please choose an appropriate title for the post.

Please choose the appropriate section so your post can be easily searched.

Please choose suitable Keywords Ex: post, video.

Browse

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

Querify Question Shop: Explore Expert Solutions and Unique Q&A Merchandise

Querify Question Shop: Explore Expert Solutions and Unique Q&A Merchandise Logo Querify Question Shop: Explore Expert Solutions and Unique Q&A Merchandise Logo

Querify Question Shop: Explore Expert Solutions and Unique Q&A Merchandise Navigation

  • Home
  • About Us
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • About Us
  • Contact Us
Home/ Questions/Q 8329

Querify Question Shop: Explore Expert Solutions and Unique Q&A Merchandise Latest Questions

Author
  • 60k
Author
Asked: November 28, 20242024-11-28T12:05:12+00:00 2024-11-28T12:05:12+00:00

Migrating My Heroku-Based SaaS to Heroku Postgres

  • 60k

Alt Text

Over the course of my 30+ year career in Information Technology, I have encountered my fair share of proof-of-concept or prototype applications which have found their way into a productional state. This has always been a direct conflict with the original intent of the work that was created.

While this should be considered some form of a compliment for a job well-done, more often than not there are decisions made in those prototyping exercises which are not labeled as production-support friendly. To some degree, this very same scenario exists with the Heroku-based SaaS fitness solution I originally created for my sister-in-law.

Now, it is time to complete this part of the journey.

Recapping the Fitness Journey (so far)

For those who are not familiar, I started building a fitness application for my sister-in-law (who is a personal trainer) in 2020 during the onset of the pandemic. This idea has since turned into a SaaS solution running in Heroku – providing a multi-tenant design for personal trainers across the United States.

Below is a listing of each article in this series:

  • Using Heroku to Quickly Build a Multi-Tenant SaaS Product – introduction and initial design
  • Integrating Twilio Into My SaaS Solution In Heroku – introduces SMS functionality for end-users
  • Leveraging CloudAMQP Within My Heroku-Based SaaS Solution – adds message-based processing for invoicing

These articles helped pave the way for the features and functionality noted in the following road map:

Release Roadmap

The 1.0.5 release is going to feature some neat stuff that uses machine learning and artificial intelligence, but a database conversion needs to happen to better prepare the RESTful API.

Destination PostgreSQL

Initially, I used MySQL for the underlying data source, because my focus was on gathering the necessary requirements for the application's initial release. Since I was already using MySQL for another application I had running in Heroku, it was easy to leverage my existing knowledge.

I knew my end state for the data layer was going to be Heroku Postgres because of the following benefits over MySQL:

  • Free & Open Source (FOSS) – my project has leveraged some amazing OSS frameworks; it only makes sense for the database to reap the benefits of open-source
  • Object-Relational Database – can define objects and table inheritance (advanced data structures)
  • Excellent for Complex Queries – will be the focus of fitness automation features currently being designed
  • Multi-Version Concurrency Control  (MVCC) – eliminates the need for a read-write lock in order to interact with data
  • Shared Across Dynos – possible to share a paid Heroku Postgres instance with multiple applications (like the application I wrote for my mother-in-law)

Migrating to Heroku Postgres

The first step in the process is to put the fitness client (written in Angular and served over Heroku via Node.js) and service (using Spring Boot) into maintenance mode. This can be completed using the following Heroku CLI command for each Dyno:

heroku maintenance:on 
Enter fullscreen mode Exit fullscreen mode

The following steps walk through the entire process of converting from MySQL to Heroku Postgres.

1. Establishing Heroku Postgres Add-On

The first step in migration from MySQL over to Heroku Postgres is to add Heroku Postgres my fitness API. This is as simple as executing the following Heroku CLI command:

heroku addons:create heroku-postgresql:hobby-dev 
Enter fullscreen mode Exit fullscreen mode

The hobby-dev plan will be temporary until I am ready to shut down my existing MySQL database. As an example, let's assume the following database results were returned from the hobby-dev instance:

Creating heroku-postgresql:hobby-dev on ⬢ sushi... free Database has been created and is available ! This database is empty. If upgrading, you can transfer ! data from another database with pg:copy Created postgresql-acute-52767 as DATABASE_URL 
Enter fullscreen mode Exit fullscreen mode

Using the heroku config CLI command, the full DATABASE_URL can be retrieved from Heroku, which includes the system account ID and password required to access the database. As an example, let's assume the following information was retrieved:

postgres://user:password@somehost.compute-1.amazonaws.com:5432/someDatabase 
Enter fullscreen mode Exit fullscreen mode

Next, I am going to use my MacBook Pro in order to work on the data conversion locally. The first step is to set the DATABASE_URL in my local environment:

export DATABASE_URL=postgres://user:password@somehost:5432/someDatabase 
Enter fullscreen mode Exit fullscreen mode

Using echo $DATABASE_URL will validate that the environmental variable is available.

2. Installing PostgreSQL Locally

To perform the migration locally, the Postgres.app (with PostgreSQL version 13 support) was installed on my MacBook Pro.

The Postgres command line tools were installed next:

sudo mkdir -p /etc/paths.d && echo /Applications/Postgres.app/Contents/Versions/latest/bin | sudo tee /etc/paths.d/postgresapp 
Enter fullscreen mode Exit fullscreen mode

I restarted my terminal session, then validated the Postgres tools were running correctly using:

which psql 
Enter fullscreen mode Exit fullscreen mode

Which responded with:

/Applications/Postgres.app/Contents/Versions/latest/bin/psql 
Enter fullscreen mode Exit fullscreen mode

I verified I could access the Postgres information from Heroku using the following command:

heroku pg:info 
Enter fullscreen mode Exit fullscreen mode

The following response was received:

=== DATABASE_URL Plan:                 Hobby-dev Status:               Available Connections:           0/20 PG Version:            13.2 Created:              2021-05-03 04:13 UTC Data Size:             7.9 MB Tables:                0 Rows:                 0/10000 (In compliance) Fork/Follow:          Unsupported Rollback:             Unsupported Continuous Protection: Off Add-on:               postgresql-acute-52767 
Enter fullscreen mode Exit fullscreen mode

3. Using pgloader To Migrate Data

pgloader is an open-source library to migrate data from MySQL into PostgreSQL. Using Homebrew, the installation was quick and easy:

brew install pgloader 
Enter fullscreen mode Exit fullscreen mode

Once installed, I was able to run pgloader using the following commands:

pgloader –version 
Enter fullscreen mode Exit fullscreen mode

The command returned the following information:

pgloader version "3.6.2" compiled with SBCL 2.0.11 
Enter fullscreen mode Exit fullscreen mode

Next, I created the PostgreSQL version of the fitness database using the following command:

createdb fitness 
Enter fullscreen mode Exit fullscreen mode

Using the database URL and the new PostgreSQL version I just created, the conversion was started using the following command:

pgloader mysql://userId:password@hostname/oldFitnessDatabase postgresql://localhost/fitness 
Enter fullscreen mode Exit fullscreen mode

From there, the pgloader command completed the migration effortlessly. It provided the following information:

2021-05-03T06:05:38.013630+01:00 LOG pgloader version "3.6.2" 2021-05-03T06:05:38.087483+01:00 LOG Migrating from #<MYSQL-CONNECTION mysql:// userId:password@hostname/oldFitnessDatabase {1004FE7A53}> 2021-05-03T06:05:38.087632+01:00 LOG Migrating into #<PGSQL-CONNECTION pgsql://john.vester@localhost:5432/fitness {1005142EA3}>  2021-05-03T06:05:42.536036+01:00 LOG report summary reset  ... report information here ...                                                              Total import time          ✓       4830   231.6 kB          3.150s 
Enter fullscreen mode Exit fullscreen mode

I was able to establish a connection to the local PostgreSQL database and confirm that all the expected data was there.

4. Getting Data Into Heroku Postgres

With the local PostgreSQL database containing the real data from MySQL, the next step is to push these changes into the Heroku Postgres instance.

In order to load the data, a compressed version of the database can be created using the following CLI command:

PGPASSWORD=mypassword pg_dump -Fc --no-acl --no-owner -h localhost -U userId fitness > fitness.dump 
Enter fullscreen mode Exit fullscreen mode

Using my existing (but rarely utilized) AWS S3 account, I uploaded the fitness.dump onto AWS S3 and generated a pre-signed URL using the following command:

aws s3 presign s3://myBucket/myKey 
Enter fullscreen mode Exit fullscreen mode

The last step was to restore the data into the newly created Heroku Postgres instance:

heroku pg:backups:restore '<SIGNED URL>' DATABASE_URL 
Enter fullscreen mode Exit fullscreen mode

The DATABASE_URL refers to the attribute added to the local environment in the “1. Establishing Heroku Postgres Add-On” section above.

I was able to establish a connection to the Heroku Postgres database and make sure all of the expected data was there.

5. Updating Spring Boot Service

With the database updated, the final step is to change the pom.xml in the Spring Boot RESTful service to remove this:

<dependency>    <groupId>mysql</groupId>    <artifactId>mysql-connector-java</artifactId>    <scope>runtime</scope> </dependency> 
Enter fullscreen mode Exit fullscreen mode

And then replace it with this:

<dependency>   <groupId>org.postgresql</groupId>   <artifactId>postgresql</artifactId>   <scope>runtime</scope> </dependency> 
Enter fullscreen mode Exit fullscreen mode

Starting the Spring Boot service resulted in no errors and the data converted without any issues.

The final step in the process is to disable maintenance mode for the fitness client and service. This can be completed using the following Heroku CLI command for each Dyno:

heroku maintenance:off 
Enter fullscreen mode Exit fullscreen mode

Conclusion

The following article demonstrated how easy it is to migrate an existing MySQL database to Heroku Postgres. Of course, I highly recommend executing and validating these steps in a non-production environment first. While the tooling appears to be top-notch and focused to convert data without any issues, it's always nice to execute such tasks in an environment which will not impact customers.

For my scenario, the cost to convert from MySQL to Heroku Postgres was a non-issue, since the price difference was only a few cents per month. However, with the Heroku Postgres implementation, it is possible for me to migrate away from the free version of MySQL for my mother-in-law's application to use the same Heroku Postgres instance.

However, for the same price I feel comfort in knowing I have a database that is focused on meeting the challenging demands ahead on my fitness application journey running a SaaS solution in Heroku.

Have a really great day!

herokumysqlpostgreswebdev
  • 0 0 Answers
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

Sidebar

Ask A Question

Stats

  • Questions 4k
  • Answers 0
  • Best Answers 0
  • Users 1k
  • Popular
  • Answers
  • Author

    How to ensure that all the routes on my Symfony ...

    • 0 Answers
  • Author

    Insights into Forms in Flask

    • 0 Answers
  • Author

    Kick Start Your Next Project With Holo Theme

    • 0 Answers

Top Members

Samantha Carter

Samantha Carter

  • 0 Questions
  • 20 Points
Begginer
Ella Lewis

Ella Lewis

  • 0 Questions
  • 20 Points
Begginer
Isaac Anderson

Isaac Anderson

  • 0 Questions
  • 20 Points
Begginer

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help

Footer

Querify Question Shop: Explore Expert Solutions and Unique Q&A Merchandise

Querify Question Shop: Explore, ask, and connect. Join our vibrant Q&A community today!

About Us

  • About Us
  • Contact Us
  • All Users

Legal Stuff

  • Terms of Use
  • Privacy Policy
  • Cookie Policy

Help

  • Knowledge Base
  • Support

Follow

© 2022 Querify Question. All Rights Reserved

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.