简体   繁体   中英

'async_generator is not a callable object' FastAPI dependency issue app

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

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/

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM