Search code examples
pythonfastapiasyncpg

How to apply transaction logic in FastAPI RealWorld example app?


I am using nsidnev/fastapi-realworld-example-app.

I need to apply transaction logic to this project.

In one API, I am calling a lot of methods from repositories and doing updating, inserting and deleting operations in many tables. If there is an exception in any of these operations, how can I roll back changes? (Or if everything is correct then commit.)


Solution

  • nsidnev/fastapi-realworld-example-app is using asyncpg.

    There are two ways to use Transactions.

    1. async with statement

    async with conn.transaction():
        await repo_one.update_one(...)
        await repo_two.insert_two(...)
        await repo_three.delete_three(...)
    
        # This automatically rolls back the transaction:
        raise Exception
    

    2. start, rollback, commit statements

    tx = conn.transaction()
    await tx.start()
    
    try:
        await repo_one.update_one(...)
        await repo_two.insert_two(...)
        await repo_three.delete_three(...)
    except:
        await tx.rollback()
        raise
    else:
        await tx.commit()
    

    Getting the connection conn in routes

    Inject conn: Connection = Depends(_get_connection_from_pool).

    from asyncpg.connection import Connection
    from fastapi import Depends
    
    from app.api.dependencies.database import _get_connection_from_pool
    
    
    @router.post(
        ...
    )
    async def create_new_article(
        ...
        conn: Connection = Depends(_get_connection_from_pool),  # Add this
    ) -> ArticleInResponse: