@@ -8,11 +8,15 @@ A highly opinionated [SQLAlchemy] extension for [FastAPI]:
88
99* Setup using environment variables to connect on DB;
1010* ` fastapi_sqla.Base ` a declarative base class to reflect DB tables at startup;
11- * ` fastapi_sqla.with_session ` a dependency to get an sqla session;
11+ * ` fastapi_sqla.Session ` a dependency to get an sqla session;
12+ * ` fastapi_sqla.open_session ` a context manager to get an sqla session;
13+ * ` fastapi_sqla.async_support.AsyncSession ` a dependency to get an async sqla session ;
14+ * ` fastapi_sqla.async_support.open_session ` a context manager to get an async sqla
15+ session;
1216* Automated commit/rollback of sqla session at the end of request before returning
1317 response;
1418* Pagination utilities;
15- * Pytest fixtures to easy writing test ;
19+ * Pytest fixtures;
1620
1721## Configuration
1822
2529
2630The only required key is ` sqlalchemy_url ` , which provides the database URL.
2731
32+ #### ` asyncio ` support using [ ` asyncpg ` ]
33+
34+ SQLAlchemy ` >= 1.4 ` supports ` asyncio ` .
35+ To enable ` asyncio ` support against a Postgres DB, install ` asyncpg ` :
36+
37+ ``` bash
38+ pip install asyncpg
39+ ```
40+
41+ And define environment variable ` async_sqlalchemy_url ` with ` postgres+asyncpg ` scheme:
42+
43+ ``` bash
44+ export async_sqlalchemy_url=postgresql+asyncpg://postgres@localhost
45+ ```
46+
2847### Setup the app:
2948
3049``` python
@@ -59,13 +78,19 @@ exception occurred:
5978``` python
6079from fastapi import APIRouter, Depends
6180from fastapi_sqla import Session
81+ from fastapi_sqla.asyncio_support import AsyncSession
6282
6383router = APIRouter()
6484
6585
6686@router.get (" /example" )
6787def example (session : Session = Depends()):
6888 return session.execute(" SELECT now()" ).scalar()
89+
90+
91+ @router.get (" /async_example" )
92+ async def async_example (session : AsyncSession = Depends()):
93+ return await session.execute(" SELECT now()" ).scalar()
6994```
7095
7196#### Using a context manager
@@ -78,18 +103,25 @@ occurred:
78103``` python
79104from fastapi import APIRouter, BackgroundTasks
80105from fastapi_sqla import open_session
106+ from fastapi_sqla import asyncio_support
81107
82108router = APIRouter()
83109
84110
85111@router.get (" /example" )
86112def example (bg : BackgroundTasks):
87113 bg.add_task(run_bg)
114+ bg.add_task(run_async_bg)
88115
89116
90117def run_bg ():
91118 with open_session() as session:
92119 session.execute(" SELECT now()" ).scalar()
120+
121+
122+ async def run_async_bg ():
123+ async with asyncio_support.open_session() as session:
124+ await session.execute(" SELECT now()" ).scalar()
93125```
94126
95127### Pagination
@@ -238,13 +270,23 @@ def db_url():
238270 return " postgresql://postgres@localhost/test_database"
239271```
240272
273+ ### ` async_sqlalchemy_url `
274+
275+ DB url to use when using ` asyncio ` support. Defaults to ` db_url ` fixture with
276+ ` postgresql+asyncpg:// ` scheme.
241277
242- ### ` session `
243278
244- Sqla session to create db fixture:
279+ ### ` session ` & ` async_session `
280+
281+ Sqla sessions to create db fixture:
245282* All changes done at test setup or during the test are rollbacked at test tear down;
246283* No record will actually be written in the database;
247- * Changes in one session need to be committed to be available from other sessions;
284+ * Changes in one regular session need to be committed to be available from other regular
285+ sessions;
286+ * Changes in one async session need to be committed to be available from other async
287+ sessions;
288+ * Changes from regular sessions are not available from ` async ` session and vice-versa
289+ even when committed;
248290
249291Example:
250292``` python
@@ -258,6 +300,15 @@ def patient(session):
258300 session.add(patient)
259301 session.commit()
260302 return patient
303+
304+
305+ @fixture
306+ async def doctor (async_session ):
307+ from er.sqla import Doctor
308+ doctor = Doctor(name = " who" )
309+ async_session.add(doctor)
310+ await async_session.commit()
311+ return doctor
261312```
262313
263314### ` db_migration `
@@ -307,3 +358,4 @@ It returns the path of `alembic.ini` configuration file. By default, it returns
307358[ FastAPI dependency injection ] : https://fastapi.tiangolo.com/tutorial/dependencies/
308359[ FastAPI background tasks ] : https://fastapi.tiangolo.com/tutorial/background-tasks/
309360[ SQLAlchemy ] : http://sqlalchemy.org/
361+ [ `asyncpg` ] : https://magicstack.github.io/asyncpg/current/
0 commit comments