FastAPI Tutorial #50: How to Implement Many-to-Many Relationships with SQLModel in Python FastAPI

Posted by


In this tutorial, we will be implementing Many-to-Many relationships in FastAPI using SQLModel. FastAPI is a modern, fast (high-performance), web framework for building APIs with Python 3.7+ based on standard Python type hints. SQLModel is a Python framework that provides a simple way to interact with databases using Python type annotations.

Before we start, make sure you have FastAPI and SQLModel installed. You can install them using pip:

pip install fastapi
pip install sqlmodel

Let’s start by creating a new FastAPI project. Create a new directory for your project and navigate to it in the terminal. Then create a new file called main.py and add the following code to it:

from fastapi import FastAPI
from sqlmodel import SQLModel, Field, Session, select

# Create FastAPI app
app = FastAPI()

# Your database connection details
DATABASE_URL = "sqlite:///test.db"

# Create a SQLite database session
def create_session():
    from sqlalchemy import create_engine
    from sqlmodel import SQLModel, Session

    engine = create_engine(DATABASE_URL)
    SQLModel.metadata.create_all(engine)
    with Session(engine) as session:
        yield session

# Define models
class User(SQLModel, table=True):
    id: int = Field(primary_key=True)
    name: str
    email: str
    articles: list['Article'] = Field(sa_column_kwargs={"secondary": "user_article"})

class Article(SQLModel, table=True):
    id: int = Field(primary_key=True)
    title: str
    body: str
    authors: list['User'] = Field(sa_column_kwargs={"secondary": "user_article"})

# Create tables
with Session(DATABASE_URL) as session:
    session.exec(
        """CREATE TABLE IF NOT EXISTS user (
            id INTEGER PRIMARY KEY,
            name VARCHAR(100),
            email VARCHAR(100)
        );"""
    )
    session.exec(
        """CREATE TABLE IF NOT EXISTS article (
            id INTEGER PRIMARY KEY,
            title VARCHAR(100),
            body TEXT
        );"""
    )
    session.exec(
        """CREATE TABLE IF NOT EXISTS user_article (
            user_id INTEGER REFERENCES user(id),
            article_id INTEGER REFERENCES article(id)
        );"""
    )

@app.post("/users/")
def create_user(user: User):
    with create_session() as session:
        session.add(user)
        session.commit()
        session.refresh(user)

    return user

@app.post("/articles/")
def create_article(article: Article):
    with create_session() as session:
        session.add(article)
        session.commit()
        session.refresh(article)

    return article

@app.post("/users/{user_id}/articles/{article_id}/")
def assign_article_to_user(user_id: int, article_id: int):
    with create_session() as session:
        user = session.get(User, user_id)
        article = session.get(Article, article_id)

        if user and article:
            user.articles.append(article)
            session.add(user)
            session.commit()
            session.refresh(user)

    return user

In this code, we have defined two models – User and Article, with a Many-to-Many relationship between them. A user can have multiple articles, and an article can have multiple users. We have also defined the database tables for these models and created a SQLite database session.

We have also defined three API endpoints – /users/, /articles/, and /users/{user_id}/articles/{article_id}/ for creating users, articles, and assigning articles to users respectively.

To run the FastAPI server, you can use uvicorn. Install uvicorn using pip:

pip install uvicorn

To start the FastAPI server, run the following command in your terminal:

uvicorn main:app --reload

Now you can test the API endpoints using a tool like Postman or curl. Create some users and articles using the /users/ and /articles/ endpoints, and then assign articles to users using the /users/{user_id}/articles/{article_id}/ endpoint.

That’s it! You have successfully implemented Many-to-Many relationships in FastAPI using SQLModel. Feel free to customize the code and add more features as needed.

0 0 votes
Article Rating

Leave a Reply

2 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
@emmanuelalder9052
2 hours ago

Congratulations on releasing your 50th video in the Python FastApi series. Keep them coming. 😁🎉🎉🎉

@emmanuelalder9052
2 hours ago

This video deserves multiple thumbs up 👍👍👍👍👍.Thanks for making and uploading this video. I've been struggling to implement this in one of the projects I'm working on. Thanks for covering this topic. Another great video, with a solid walking through. I will definately keep coming back to this one. Can't wait for your next FastApi SQLModel video. Happy I found your channel. Thank you.

2
0
Would love your thoughts, please comment.x
()
x