Note: SQLAlchemy has all the code needed for us to interact with the database and write python code to do so, but it does not know how to communicate with the Database itself.
Having said that, we would need to install the driver separately
In our Postgres case that would be psycopg
Usually all ORMs work like this where you need the driver separately
Once installed we will create a file called database.py in our App folder
This file will handle our database connection
In this file we will have the following:
# Imports for SQLAlchemyfrom sqlalchemy import create_enginefrom sqlalchemy.ext.declarative import declarative_basefrom sqlalchemy.orm import sessionmaker# Database connection string formatSQLALCHEMY_DATABASE_URL ='postgresql://<username>:<password>@<ip-address/hostname>/<databasename>'# Example:# SQLALCHEMY_DATABASE_URL = 'postgresql://postgres:Password1@localhost/fastapi'# Create engine for interacting with databaseengine =create_engine(SQLALCHEMY_DATABASE_URL)# However if we want to interact with the database# We will need to set up a sessionSessionLocal =sessionmaker(autocommit=False, autoflush=False, bind=engine)# Note the sessionmaker params are default values# We additionally need to define our base class# This is used for all models that we will be definingBase =declarative_base()
Now that this is set up, we will create a new file called models.py
This is where all our database tables will be created
Each model is a table
The file contains the following:
# Base needs to be imported from our database filefrom app.database import Base# Columns and Datatypes required for SQLfrom sqlalchemy import Column, Integer, String, Boolean# Different expressionsfrom sqlalchemy.sql.expression import null# Define classclassPost(Base):# Define Tablename __tablename__ ='posts'# Define Columnsid=Column(Integer, primary_key=True, nullable=False) title =Column(String, nullable=False) content =Column(String, nullable=False) published =Column(Boolean, server_default='TRUE', nullable=False)# Note: Template for Column is# Column(DATATYPE?, PRIMARY_KEY?, NULLABLE?, DEFAULT VALUE?)
Now that this is created we will need to set up the following line in the main.py file
# Import the models.py filefrom.import models# Import the engine and SessionLocal form database.pyfrom app.database import engine, SessionLocal# Set up the creationmodels.Base.metadata.create_all(bind=engine)# We will additionally have to import the dependencydefget_db(): db =SessionLocal()try:yield dbfinally: db.close()
Now this should be good to go
Every time we will interact with the database we will get a session
Once we are done interacting, the session will close
We can start setting up paths to our App using this code
# We will have to import Depeds from FastAPIfrom fastapi import Depends, FastAPI, Response, status, HTTPException# We also need to import Session from SQLAlchemyfrom sqlalchemy.orm import Session# Testing SQLAlchemy@app.get("sqlalchemy")deftest_post(db: Session =Depends(get_db)):return{"status":"success"}
By setting all of this up, SQLAlchemy will connect to the Database
Check if the tables exist
If they don't it will create them
If they do it will mode on
But now if we connect to the database we should see the table created from scratch
Cleanup
Just to keep everything clean, we will move the dependency code in our database.py file
This keeps everything clean, all the database stuff with the database stuff
Additionally we will have to import this in our main.py file
database.py
from requests import Sessionfrom sqlalchemy import create_enginefrom sqlalchemy.ext.declarative import declarative_basefrom sqlalchemy.orm import sessionmaker# Template:SQLALCHEMY_DATABASE_URL ='postgresql://<username>:<password>@<ip-address/hostname>/<databasename>'# Engine for databaseengine =create_engine(SQLALCHEMY_DATABASE_URL)# Session to interact with said databaseSessionLocal =sessionmaker(autocommit=False, autoflush=False, bind=engine)# Base for defining Database modelsBase =declarative_base()# Dependencydefget_db(): db =SessionLocal()try:yield dbfinally: db.close()