Configuring Python FastAPI with SqlAlchemy and Alembic
FastAPI is a promising framework to build high performance web applications that needs Async support. It also brings in best practices for a high quality production application.
Let’s take a quick view of few building blocks that we will use in this article.
FastAPI is build using two important framework for well defined responsibilities :
Starlette is a lightweight ASGI framework/toolkit, which is ideal for building high performance asyncio services.
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 (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.
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.'
But uvicorn seems functional though installation had an error. I didn’t fully understand the reason., But it is not blocking our project.
Environment based configuration
pipenv install python-dotenv
Directory structure (end result )
│ ├── __init__.py
│ ├── config
│ │ ├── __init__.py
│ │ ├── prod.env
│ │ └── qa.env
│ ├── database.py
│ ├── main.py
│ ├── models
│ │ ├── __init__.py
│ └── schemas
│ ├── README
│ ├── env.py
│ ├── script.py.mako
│ └── versions
│ └── 66d8a54cd297_initial_tables.py
Create a directory
config and have environment configurations there.
from pydantic import BaseSettingsclass Settings(BaseSettings):
# default conf goes here
app_name: str = "Awesome API"
items_per_user: int = 50 class Config:
env_file = ".env"
# Initialize alembic database migration flow
$ alembic init db-migration
- Update alembic’s env.py with environment based
get_urlmethod as shown below
run_migration_offlineas shown below
run_migration_onlineas shown below
target_metadataThis is needed for
autogenerationof migration scripts
Alembic autogeneration of migration scripts
- For autogeneration to work, alembic should be able to detect all models that we have in the application.
__init__.pywill help to automatically add all models that exists into
__all__so that we can do
import *as shown in
We make use of autogeneration of schema changes. With this, we can make changes to database models and run autogenerate — this will generate the changes as script.
# 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 history - verbose
- 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.
- Full stack, modern web application generator. Using FastAPI, PostgreSQL as database, Docker, automatic HTTPS and more
- Async — Await in FastAPI with good explanation on concurrency vs parallelism
- Alembic’s documentation on getting started
- API documentation metadata configuration
- Application configuration management
- FastAPI document has few suggestions on folder structures.