Trusted answers to developer questions
Trusted Answers to Developer Questions

Related Tags


How to use PostgreSQL database in FastAPI

Njoku Ifeanyi Gerald

FastAPI is a Python web framework specially for building APIs. In this article, we will be looking into PostgreSQL with Django.

PostgreSQL is an object-relational database that uses and extends the SQL language to scale and store big complicated data in the database.

The example below demonstrates how PostgreSQL can be used alongside FastAPI.

Step 1


pip install pipenv
pipenv shell
pipenv install fastapi fastapi-sqlalchemy pydantic alembic psycopg2 uvicorn python-dotenv

Step 2

Create a file and name it This file is responsible for creating the model for the database.

from sqlalchemy import Column, DateTime, ForeignKey, Integer, String, Float
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relationship
from sqlalchemy.sql import func

Base  = declarative_base()

class Book(Base):
    __tablename__ = 'book'
    id  = Column(Integer, primary_key=True, index=True)
    title = Column(String)
    rating = Column(Float)
    time_created = Column(DateTime(timezone=True),
    time_updated = Column(DateTime(timezone=True),
    author_id = Column(Integer, ForeignKey(''))

    author = relationship('Author')

class Author(Base):
    __tablename__ = 'author'
    id = Column(Integer, primary_key=True)
    name = Column(String)
    age = Column(Integer)
    time_created = Column(DateTime(timezone=True),
    time_updated = Column(DateTime(timezone=True),

Step 3

Create another file and name it It is used to write how an object in a model can be easily mapped using ORMobject-relational mapper.

# build a schema using pydantic
from pydantic import BaseModel

class Book(BaseModel):
    title: str
    rating: int
    author_id: int

    class Config:
        orm_mode = True

class Author(BaseModel):

    class Config:
        orm_mode = True

Step 4

Create a file and name it This file is used to create functions or classes that visualize how a route will operate.

import uvicorn
from fastapi import FastAPI
from fastapi_sqlalchemy import DBSessionMiddleware, db

from schema import Book as SchemaBook
from schema import Author as SchemaAuthor

from schema import Book
from schema import Author

from models import Book as ModelBook
from models import Author as ModelAuthor

import os
from dotenv import load_dotenv


app = FastAPI()

# to avoid csrftokenError
app.add_middleware(DBSessionMiddleware, db_url=os.environ['DATABASE_URL'])

async def root():
    return {"message": "hello world"}'/book/', response_model=SchemaBook)
async def book(book: SchemaBook):
    db_book = ModelBook(title=book.title, rating=book.rating, author_id = book.author_id)
    return db_book

async def book():
    book = db.session.query(ModelBook).all()
    return book'/author/', response_model=SchemaAuthor)
async def author(author:SchemaAuthor):
    db_author = ModelAuthor(, age=author.age)
    return db_author

async def author():
    author = db.session.query(ModelAuthor).all()
    return author

# To run locally
if __name__ == '__main__':, host='', port=8000)

Step 5

  • Create an environment file and name it .env.
  • Inside the .env file, do the following:

DATABASE_URI = 'postgresql://postgres:<password>@localhost/<name_of_the_datbase>'

Here, we will add a link to our PostgreSQL database.

Step 6

After it, run this command:

alembic init alembic

It will create a folder called alembic. Inside the folder, go to the file and do the following:

from logging.config import fileConfig

from sqlalchemy import engine_from_config
from sqlalchemy import pool

from alembic import context

# My code
import os,sys
from dotenv import load_dotenv

BASE_DIR= os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
load_dotenv(os.path.join(BASE_DIR, '.env'))

# This is the Alembic Config object, which provides
# Access to the values within the .ini file in use.
config = context.config

#  Making a connection
config.set_main_option('sqlalchemy.url', os.environ['DATABASE_URL'])

# Interpret the config file for Python logging.
# This line sets up loggers basically.

import models
# add your model's MetaData object here
# for 'autogenerate' support
# from myapp import mymodel
# target_metadata = mymodel.Base.metadata
target_metadata = models.Base.metadata

# other values from the config, defined by the needs of,
# can be acquired:
# my_important_option = config.get_main_option("my_important_option")
# ... etc.

def run_migrations_offline():
    """Run migrations in 'offline' mode.

    This configures the context with just a URL
    and not an Engine, though an Engine is acceptable
    here as well.  By skipping the Engine creation
    we don't even need a DBAPI to be available.

    Calls to context.execute() here emit the given string to the
    script output.

    url = config.get_main_option("sqlalchemy.url")
        dialect_opts={"paramstyle": "named"},

    with context.begin_transaction():

def run_migrations_online():
    """Run migrations in 'online' mode.

    In this scenario we need to create an Engine
    and associate a connection with the context.

    connectable = engine_from_config(

    with connectable.connect() as connection:
            connection=connection, target_metadata=target_metadata

        with context.begin_transaction():

if context.is_offline_mode():

Step 7

Run the following code to enable migration.

alembic upgrade head

alembic revision --autogenerate -m "New Migration"

Step 8

To kickstart the app, use:

uvicorn main:app --reload

Then go here, and to use the app go here.




Njoku Ifeanyi Gerald

View all Courses

Keep Exploring