mfreeborn / fastapi-sqlalchemy

Adds simple SQLAlchemy support to FastAPI
MIT License
594 stars 34 forks source link

Incompatible with later versions of FastAPI/Pydantic? #46

Closed willarmiros closed 11 months ago

willarmiros commented 11 months ago

I am using fastapi-sqlalchemy for a project that also uses Pydantic to define API object models. We recently upgraded to Pydantic 2.x, and our application works fine except for one instance where we use the db object outside of a route, to seed our Database.

The version upgrades were:

FastAPI: 0.88.0 -> 0.100.1
Pydantic: 1.10.8 -> 2.1.1

The code where we're using fastapi-sqlalchemy looks like:

if __name__ == "__main__":
    databaseCredentials = json.loads(os.environ["DB_CREDENTIALS"])
    databaseHostname = databaseCredentials["host"]
    databasePort = databaseCredentials["port"]
    databaseName = databaseCredentials["dbname"]
    databaseUrl = f"postgresql+psycopg2://{databaseCredentials['username']}:{databaseCredentials['password']}@{databaseHostname}:{databasePort}/{databaseName}"

    app = FastAPI()
    app.add_middleware(DBSessionMiddleware, db_url=databaseUrl)

    with db():
        run_db_seed()

The command we use to run the database seeding python script is:

docker-compose run app poetry run python -m apiserver.domain.db_seed

And the stacktrace we're getting is:

Traceback (most recent call last):
  File "<frozen runpy>", line 198, in _run_module_as_main
  File "<frozen runpy>", line 88, in _run_code
  File "/app/apiserver/domain/db_seed.py", line 278, in <module>
    with db():
  File "/root/.cache/pypoetry/virtualenvs/radar-api-9TtSrW0h-py3.11/lib/python3.11/site-packages/fastapi_sqlalchemy/middleware.py", line 72, in __enter__
    raise SessionNotInitialisedError
fastapi_sqlalchemy.exceptions.SessionNotInitialisedError: 
        Session not initialised! Ensure that DBSessionMiddleware has been initialised before
        attempting database access.

Anyone else experiencing anything similar? Given there hasn't been a release in ~3 years, is it just time to move on from the library?

willarmiros commented 11 months ago

Turns out this was an issue with upgrading the FastAPI version. In FastAPI v0.91.0, they switched the middleware initialization logic to be lazily initialized on the first server request: https://fastapi.tiangolo.com/release-notes/#0910

Because our script had no server request, the middleware was never initialized and we got this error. To fix, you can simply manually instantiate the middleware:

app = FastAPI()
DBSessionMiddleware(app, databaseUrl)