Reputation: 91
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
Upvotes: 3
Views: 5301
Reputation: 91
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.
Upvotes: 3
Reputation: 4456
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/
Upvotes: 0