2

I am trying to create a FastAPI and async sqlalchemy.

The get_db dependency causes a weird TypeError: <async_generator object get_db at 0x7ff6d9d9aa60> is not a callable object issue.

Here's my code:

db.py

from typing import Generator
from .db.session import SessionLocal

async def get_db() -> Generator:
    try:
        db = SessionLocal()
        yield db
    finally:
        await db.close()

session.py

from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
from .core.config import settings

engine = create_async_engine(
    settings.SQLALCHEMY_DATABASE_URI,
    pool_pre_ping=True
)
SessionLocal = AsyncSession(
    autocommit=False,
    autoflush=False,
    bind=engine
)

I followed almost of the instructions posted here: https://6060ff4ffd0e7c1b62baa6c7--fastapi.netlify.app/advanced/sql-databases-sqlalchemy/#more-info

joween
  • 61
  • 2
  • 8

2 Answers2

1

I have figured this out, basically when you call the generator get_db() as a dependency for a FastAPI endpoint, you basically just call it as get_db without the parenthesis.

For example:

from typing import List, Any

from fastapi import APIRouter, HTTPException, Depends, status
from sqlalchemy.ext.asyncio import AsyncSession

from . import models, crud, schemas
from .deps.db import get_db

router = APIRouter()


@router.post('/',
             response_model=schemas.StaffAccount,
             status_code=status.HTTP_201_CREATED)
async def create_staff_account(
        db: AsyncSession = Depends(get_db),
        staff_acct: schemas.StaffAccountCreate = Depends(schemas.StaffAccountCreate)
) -> Any:
    q = await crud.staff.create(db=db, obj_in=staff_acct)
    if not q:
        raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
                            detail='An error occurred while processing your request')
    return q

This is such a minor detail, that can get in the way of some beginners (like me). So please look more closely at your code.

Dharman
  • 30,962
  • 25
  • 85
  • 135
joween
  • 61
  • 2
  • 8
  • Upvoting the question and the answer. This saved me a lot of time and headache! Keep it mind the Depends expects this kind of values - https://fastapi.tiangolo.com/tutorial/dependencies/ – jcdevilleres Sep 18 '21 at 07:41
0

The problem is

engine = create_async_engine(
settings.SQLALCHEMY_DATABASE_URI,
pool_pre_ping=True
)

You are filling engine with a promise that has to be fulfilled yet. Basically the async functionality allows you to go on with the code while some I/O or networking stuff is still pending.

So, you are passing the engine as parameter, although the connection may not have been established yet.

You should await for the return of the engine before using it as a parameter for other functions.

Here's some more information about the async functionality of python

https://www.educba.com/python-async/

lsabi
  • 3,641
  • 1
  • 14
  • 26