Configuring Python FastAPI with SqlAlchemy and Alembic

FastAPI

FastAPI is build using two important framework for well defined responsibilities :

Starlette

Starlette is a lightweight ASGI framework/toolkit, which is ideal for building high performance asyncio services.

Pydantic

pydantic enforces type hints at runtime, and provides user friendly errors when data is invalid. We can define how data should be in pure python and validate it easily with pydantic.

ASGI specification

ASGI (Asynchronous Server Gateway Interface) is a spiritual successor to WSGI, intended to provide a standard interface between async-capable Python web servers, frameworks, and applications.

Uvicorn server

Uvicorn is a lightning-fast ASGI server, built on uvloop and httptools.

Alembic

Alembic is a lightweight database migration tool for usage with the SQLAlchemy Database Toolkit for Python

Getting started

Let’s install only libraries that we will use:

# Use python 3.6+
pipenv install fastapi uvicorn sqlalchemy alembic

Uvicorn installation error

On doing the above installation of uvicorn, in my case resulted in an error. One of the dependency of uvicorn → unicorn errored out saying :

ERROR: Cannot use 'python', Python 2.4 or later is required.", '           Note that Python 3 or later is not yet supported.'

Environment based configuration

pipenv install python-dotenv
.
├── Dockerfile
├── Pipfile
├── Pipfile.lock
├── README.md
├── alembic.ini
├── app
│ ├── __init__.py
│ ├── config
│ │ ├── __init__.py
│ │ ├── prod.env
│ │ └── qa.env
│ ├── database.py
│ ├── main.py
│ ├── models
│ │ ├── __init__.py
│ └── schemas
├── migration
│ ├── README
│ ├── env.py
│ ├── script.py.mako
│ └── versions
│ └── 66d8a54cd297_initial_tables.py
├── start.sh
#__init__.py
from pydantic import BaseSettings
class Settings(BaseSettings):
# default conf goes here
app_name: str = "Awesome API"
admin_email: str
items_per_user: int = 50
class Config:
env_file = ".env"

Alembic

# Initialize alembic database migration flow
$ alembic init db-migration
  • Update alembic’s env.py with environment based db_url with custom get_url method as shown below
  • update run_migration_offline as shown below
  • update run_migration_online as shown below
  • update target_metadata This is needed for autogeneration of migration scripts
env.py

Alembic autogeneration of migration scripts

  • For autogeneration to work, alembic should be able to detect all models that we have in the application.
  • Below __init__.py will help to automatically add all models that exists into __all__ so that we can do import * as shown in env.py
# This will scan the models and generate upgrade & downgrade scripts
alembic revision --autogenerate -m “Initial tables”

Running db migration

Detailed information on alembic commands can be found here.
Here is a quick reference:

# following command will run all migration script and bring it to latest version
alembic upgrade head
# If we like to incrementally upgrade and check for some errors
alembic upgrade +1
# To undo last migration
alembic downgrade -1
# To get more information
alembic current
alembic history - verbose

Summary

  • SQLAlchemy Model creation is well documented in fastapi documentation. So this article is not diving into those details.
  • Configuring alembic with fastapi and getting autogeneration working is little tricky.
  • Above setup with env based config should come handy, if you are trying to setup one.

Useful links

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Sairam Krish

Sairam Krish

432 Followers

Software Architect ★ Data engineer ★ Committed to improve data science productivity