If you’ve been interested in deploying a web app to the cloud, this article is for you!
In this tutorial, I’m going to show you how to make the web app and database shown in the gif above, and also deploy it to Heroku so it can be used by anyone.
This guide is divided into 3 sections:
- Creating a Flask app (the web application for submitting the form)
- Setting up a Postgres database with Python (to store the data from the submitted forms)
- Deploying the application to Heroku (by hosting the application in the cloud so anyone can use it)
If this is your first time working with any of these technologies, I provide a brief explanation at the beginning of each section about how each technology works.
This guide is targeted towards beginner to intermediate programmers who have some familiarity with programming and using the command line.
You will need the following to get started:
- A Postgres database: You need to download and install Postgres on your local computer.
- Python 3.6 or newer: Python installers for different versions and OS are available for download here.
- Heroku Account: You need to create a free Heroku account if you do not already have one. This is where we will deploy the flask app and connect it to a remote Postgres database.
Once you have all the above installed, we can start by setting up our development environment.
Creating a Flask App for a Registration Form
In this section, we’re going to create the Flask app shown above.
I’ve created an example Flask app that renders a simple registration form used to collect information from a user.
Flask is one of the most popular web frameworks written in Python. The flask application I made first makes a request to the endpoints defined in the
app/routes.py file to retrieve the data that is displayed in the registration form.
It then renders the HTML pages contained in the
Template folder using the Jinja Template library.
Instead of starting from scratch, let’s make a copy of the Flask app I created by cloning the Github repo.
Open a command line tool and run the following commands:
If you ever get lost, you can view the completed project here: Flask-Postgres App
Next, we’re going to create a virtual environment for this project and install the required dependencies. A virtual environment is an isolated environment for different Python projects. They are helpful when keeping packages and dependencies separate between different projects.
Depending on your computer’s operating system, run the following commands:
To test if our environment is properly set up, let’s try launching the application by entering
flask run in the virtual environment.
Now you can enter http://127.0.0.1:5000/ in your browser and view the web form!
Adding Input Validations for the Registration Form
To get more familiar with the code, let’s add input validations to the form class.
We want our app to prevent users from filling out the form with the same username or email address multiple times.
wtforms, you can create a custom validator that is automatically added to each field by creating a method with the name
validate_<field_name>. In the
app/form.py file, we will add two methods:
validate_username. We will query the Registrations table (we’ll create this table later) username and email entered by the user. If it returns a value, we will raise a validation error.
form.py file and first import Registrations from the
models.py file (we’ll add this file later).
And in the
RegistrationForm class, add the following validation methods:
Now let’s add in the
models.py file so we can test the input validation.
Creating a PostgreSQL Database
First, we need to create the database that
models.py will connect to.
For this tutorial, we’ll be using a PostgreSQL database. PostgreSQL is an open-source, object-relational database. And the best part is that it’s completely free.
Let’s start by creating a new Postgres database to store the data from submitted registration forms. If you already have a Postgres database, feel free to jump to the next section to start connecting your Flask app to the database.
If you haven’t yet, download and install Postgres on your computer.
Now open a new command line window and type
psql is a terminal-based interface to manage your Postgres databases.
Run the command
create database [database name]; to create a new database.
Below is a list of popular
psql commands to manage your database:
l: list all available databases
dt: list all tables
d table_name: describe a table, showing its columns, column type, etc.
du: list all users and their roles.
?: get a list of all psql commands`q`: to quit psql terminal
Alternatively, you can avoid memorizing the different psql commands and use Arctype’s free SQL editor that provides a modern interface for managing both Postgres and MySQL databases:
Connecting a Flask App To a Local Postgres Database
Next, we’ll create the database connection to our new Postgres database that will be used inside our
models.py file. To get started, there are 3 packages to install:
flask-sqlalchemy: A python extension for managing databases
flask-migrate: For making updates to an existing database
Pyscopg2: A Postgresql database adapter for python
In the following sections, I’ll show how to use each package to configure and integrate the Postgres database with the Flask application. The end result will be a Flask app able to add new entries to a Postgres table.
Manage Postgres Databases From Python With SQLAlchemy
SQLAlchemy is a library that provides a way to seamlessly integrate python programs and databases. We will use SQLAlchemy as an Object Relational Mapper to convert python classes to tables in our Postgres database.
Flask-SQLAlchemy automatically translates the created models to the syntax of any database (Postgres in our case).
To interact with our database from the application, we need to add the following configuration variables to the config file:
SQLALCHEMY_DATABASE_URI: This is the connection string that tells our Flask app which database to connect to. The usual form of the Postgres database connection string is
postgresql://localhost/[YOUR_DATABASE_NAME]. If your Postgres user has a password, you will need to use a different URI variant.
SQLALCHEMY_TRACK_MODIFICATIONS: We set this to
Falseso we do not get a warning from Flask every time we make a change to the application.
To make the above changes, open the
config.py file and add the following variables to the
In the next session, we’ll use the
flask-migrate package to seamlessly handle changes to our database structure.
Setting up Flask-Migrate To Manage Database Structures
As we scale our application, we may need to make structural changes to our tables without losing all the data already in the database. Flask-Migrate is a python extension that handles SQLAlchemy database migrations automatically using Alembic. It also supports multiple database migrations and other functionalities.
Now, we will add a database object that represents our database and also create an instance of the migration class to handle database migrations.
app/__init__.py and import the flask-migrate and SQLAlchemy packages:
Then add the following variables:
Set up the PostgreSQL Database Model
Now we’re finally ready to create the
models.py file to set up our database model. Database models are used to represent tables and their structures in the database; they determine the schema of the table.
models.py will define the structure of our tables and other necessary table information. We need to create a model (Class) whose attributes are the same as the data fields we intend to store in the database tables.
Then create a class with the attributes for each data field in the registration form:
The last step is importing the model in the
from app import models.
If you are working with your own database, we’ve created a free tool to design database schemas.
Creating a New Registrations Table in Postgres Using Flask
Next, we will instantiate the database from the command line by running
flask db init in the virtual environment.
Ensure that your
FLASK_APP environment variable is set before you run this command. You can run the following commands to check:
After you run
flask db init you should see the following output:
From the command logs, we can see that a migrations folder is created in our application. This folder contains files that are needed to migrate tables and update table schemas on our database.
Now that we have a migrations repository, it’s time to migrate the
Registration table to the database using the
Ensure that your Postgres server is up, then run the
flask db migrate command to automatically migrate our SQLAlchemy database to the Postgres database that we assigned earlier with the URI in the config file.
flask db migrate does not make any changes to the database; it only generates the migration script. To make the changes, we use the
flask db upgrade command. You can also revert the changes by using
flask db downgrade.
Open Arctype to check if the table was successfully migrated to the local Postgres database.
Inserting Data From a Flask App in Postgres
In this section, we’ll update the route function to add the data collected from the webpage into the database. First, we will update our imports by including our database instance and table model in the
In the route function, we will create an instance of the
Registration class and update it with information collected from the form. We then proceed to add and commit the instance to the database.
Add the following
if statement inside the
index() function in
Testing if the Flask App Is Inserting Data in Postgres
Let’s test our application locally one more time before deploying to Heroku:
Navigate to http://127.0.0.1:5000/ and submit the form. After submitting the form, you can check that a new entry was added to your database by checking the
Registrations table in Arctype:
Deploying the Flask App and Postgres Database To Heroku
Now that we have tested our application locally, it’s time to deploy the application and our Postgres database to Heroku so we can access it from anywhere.
The first step is downloading and installing the Heroku CLI. Then we can log into Heroku from the command line with:
Once we’re logged in, we can create a new app on Heroku by running:
Heroku create [app-name]. Heroku apps are in a global namespace, therefore you need to choose a unique name for your application. If you do not specify a name for your application, Heroku will generate a random name for your application.
To proceed with development, we need to update our
requirements.txt file and create a
Procfile in our root directory. The
Procfile is used to declare the commands run by the app on Heroku.
Next, we need to install
gunicorn, which is a python server needed to run the application on Heroku. In the activated python environment, run
pip install gunicorn to install the
pip freeze > requirements.txt to update the requirements file. The
procfile defines processes based using the following format
<process type>: <command>. Since our application contains a web server (gunicorn), the process type is web and the command will launch the gunicorn server. Therefore, we need to run the command below on the terminal to create the Procfile:
echo web: gunicorn app:app > Procfile
Heroku has different service plans for its PostgreSQL offering. Choosing a plan for your application depends on the characteristics of your application and its bandwidth for service downtimes. In this tutorial, we will use the hobby-dev plan, which is free and serves the purpose we need it for.
Now, we will create a hobby-dev Postgres database for our application using the
heroku addons:create heroku-postgresql:hobby-dev --app app-name command:
More information on working with Postgres databases can be found here.
We’ve created a new remote Postgres database for our application on Heroku, so we need to update the
SQLALCHEMY_DATABASE_URI variable in the
config.py file with the new database URI. To retrieve the remote database URI, we use the
heroku config --app app-name command.
Once the URI is updated, the final step is deploying our application to Heroku’s servers.
First, we will commit all our files and push them to the Heroku master branch. Run
git add . and
git commit -m “heroku commit”, then
git push heroku main to deploy to Heroku.
Your app is now live at
Migrating Tables From a Local Postgres Database To Heroku
The last step is migrating the
Registrations table that we created in our local Postgres database to the new Heroku database instance. We can do this by running
db create_all() from the Heroku python terminal:
To check if the
Registrations table was successfully created, connect to the Heroku database from Arctype and you should see the Registrations table.
You are now the proud creator of a web app that anyone with internet access can use, from anywhere in the world. Let’s zoom out and review what we covered:
- How a Flask app works
- Creating a Postgres database
- Creating a database model in Python using SQLAlchemy
- Migrating a database in Python using flask-migrate
- Inserting data into a Postgres database from a Flask app
- Deploying a Flask app and Postgres database to Heroku