From f8a365c0cf897f3ab72d72770c1480680369d637 Mon Sep 17 00:00:00 2001 From: il-s Date: Wed, 24 Nov 2021 23:04:52 +0700 Subject: [PATCH 1/8] Add router for async SQLAlchemy mode --- fastapi_crudrouter/core/async_sqlalchemy.py | 168 ++++++++++++++++++++ 1 file changed, 168 insertions(+) create mode 100644 fastapi_crudrouter/core/async_sqlalchemy.py diff --git a/fastapi_crudrouter/core/async_sqlalchemy.py b/fastapi_crudrouter/core/async_sqlalchemy.py new file mode 100644 index 00000000..8df31940 --- /dev/null +++ b/fastapi_crudrouter/core/async_sqlalchemy.py @@ -0,0 +1,168 @@ +from typing import Any, Callable, List, Type, Generator, Optional, Union + +from fastapi import Depends, HTTPException + +from . import CRUDGenerator, NOT_FOUND, _utils +from ._types import DEPENDENCIES, PAGINATION, PYDANTIC_SCHEMA as SCHEMA +#from fastapi_crudrouter.core._base import CRUDGenerator, NOT_FOUND, _utils +#from fastapi_crudrouter.core._types import DEPENDENCIES, PAGINATION, PYDANTIC_SCHEMA as SCHEMA + +try: + from sqlalchemy.orm import Session + from sqlalchemy.ext.declarative import DeclarativeMeta as Model + from sqlalchemy.exc import IntegrityError, NoResultFound + from sqlalchemy.future import select +except ImportError: + Model: Any = None # type: ignore + sqlalchemy_installed = False +else: + sqlalchemy_installed = True + Session = Callable[..., Generator[Session, Any, None]] + + +class AsyncSQLAlchemyCRUDRouter(CRUDGenerator[SCHEMA]): + def __init__( + self, + schema: Type[SCHEMA], + db_model: Model, + db: "Session", + create_schema: Optional[Type[SCHEMA]] = None, + update_schema: Optional[Type[SCHEMA]] = None, + prefix: Optional[str] = None, + tags: Optional[List[str]] = None, + paginate: Optional[int] = None, + get_all_route: Union[bool, DEPENDENCIES] = True, + get_one_route: Union[bool, DEPENDENCIES] = True, + create_route: Union[bool, DEPENDENCIES] = True, + update_route: Union[bool, DEPENDENCIES] = True, + delete_one_route: Union[bool, DEPENDENCIES] = True, + delete_all_route: Union[bool, DEPENDENCIES] = True, + **kwargs: Any + ) -> None: + assert ( + sqlalchemy_installed + ), "SQLAlchemy must be installed to use the SQLAlchemyCRUDRouter." + + self.db_model = db_model + self.db_func = db + self._pk: str = db_model.__table__.primary_key.columns.keys()[0] + self._pk_type: type = _utils.get_pk_type(schema, self._pk) + + super().__init__( + schema=schema, + create_schema=create_schema, + update_schema=update_schema, + prefix=prefix or db_model.__tablename__, + tags=tags, + paginate=paginate, + get_all_route=get_all_route, + get_one_route=get_one_route, + create_route=create_route, + update_route=update_route, + delete_one_route=delete_one_route, + delete_all_route=delete_all_route, + **kwargs + ) + + def _get_all(self, *args: Any, **kwargs: Any) -> Callable[..., List[Model]]: + async def route( + db: Session = Depends(self.db_func), + pagination: PAGINATION = self.pagination, + ) -> List[Model]: + skip, limit = pagination.get("skip"), pagination.get("limit") + + res = await db.execute(select(self.db_model) + .order_by(getattr(self.db_model, self._pk)) + .limit(limit) + .offset(skip) + ) + res = res.all() + + model: Model + db_models: List[Model] = [] # [(row,) for row in res] + for row in res: + (model,) = row + # print(model) + db_models.append(model) + + return db_models + + return route + + def _get_one(self, *args: Any, **kwargs: Any) -> Callable[..., Model]: + async def route( + item_id: self._pk_type, db: Session = Depends(self.db_func) # type: ignore + ) -> Model: + model: Model + try: + (model,) = (await db.execute(select(self.db_model).where(self.db_model.id == item_id))).one() + except NoResultFound: + model = None + + print([model]) + if model: + return model + else: + raise NOT_FOUND from None + + return route + + def _create(self, *args: Any, **kwargs: Any) -> Callable[..., Model]: + async def route( + model: self.create_schema, # type: ignore + db: Session = Depends(self.db_func), + ) -> Model: + try: + db_model: Model = self.db_model(**model.dict()) + db.add(db_model) + await db.commit() + await db.refresh(db_model) + return db_model + except IntegrityError: + await db.rollback() + raise HTTPException(422, "Key already exists") from None + + return route + + def _update(self, *args: Any, **kwargs: Any) -> Callable[..., Model]: + async def route( + item_id: self._pk_type, # type: ignore + model: self.update_schema, # type: ignore + db: Session = Depends(self.db_func), + ) -> Model: + try: + db_model: Model = await self._get_one()(item_id, db) + + for key, value in model.dict(exclude={self._pk}).items(): + if hasattr(db_model, key): + setattr(db_model, key, value) + + await db.commit() + await db.refresh(db_model) + + return db_model + except IntegrityError as e: + await db.rollback() + self._raise(e) + + return route + + def _delete_all(self, *args: Any, **kwargs: Any) -> Callable[..., List[Model]]: + async def route(db: Session = Depends(self.db_func)) -> List[Model]: + await db.execute('delete from '+self.db_model.__tablename__) + await db.commit() + return await self._get_all()(db=db, pagination={"skip": 0, "limit": None}) + + return route + + def _delete_one(self, *args: Any, **kwargs: Any) -> Callable[..., Model]: + async def route( + item_id: self._pk_type, db: Session = Depends(self.db_func) # type: ignore + ) -> Model: + db_model: Model = await self._get_one()(item_id, db) + await db.delete(db_model) + await db.commit() + + return db_model + + return route From dbd11da1b29d2695bfff5aeae81bc4f8e14137eb Mon Sep 17 00:00:00 2001 From: il-s Date: Thu, 25 Nov 2021 09:34:37 +0700 Subject: [PATCH 2/8] Modify __init_.py --- fastapi_crudrouter/__init__.py | 2 ++ fastapi_crudrouter/core/__init__.py | 2 ++ 2 files changed, 4 insertions(+) diff --git a/fastapi_crudrouter/__init__.py b/fastapi_crudrouter/__init__.py index 2218903d..44627ab6 100644 --- a/fastapi_crudrouter/__init__.py +++ b/fastapi_crudrouter/__init__.py @@ -4,6 +4,7 @@ MemoryCRUDRouter, OrmarCRUDRouter, SQLAlchemyCRUDRouter, + AsyncSQLAlchemyCRUDRouter, TortoiseCRUDRouter, ) @@ -12,6 +13,7 @@ __all__ = [ "MemoryCRUDRouter", "SQLAlchemyCRUDRouter", + "AsyncSQLAlchemyCRUDRouter", "DatabasesCRUDRouter", "TortoiseCRUDRouter", "OrmarCRUDRouter", diff --git a/fastapi_crudrouter/core/__init__.py b/fastapi_crudrouter/core/__init__.py index 68b8947c..d4e7d8ec 100644 --- a/fastapi_crudrouter/core/__init__.py +++ b/fastapi_crudrouter/core/__init__.py @@ -5,6 +5,7 @@ from .mem import MemoryCRUDRouter from .ormar import OrmarCRUDRouter from .sqlalchemy import SQLAlchemyCRUDRouter +from .async_sqlalchemy import AsyncSQLAlchemyCRUDRouter from .tortoise import TortoiseCRUDRouter __all__ = [ @@ -13,6 +14,7 @@ "NOT_FOUND", "MemoryCRUDRouter", "SQLAlchemyCRUDRouter", + "AsyncSQLAlchemyCRUDRouter", "DatabasesCRUDRouter", "TortoiseCRUDRouter", "OrmarCRUDRouter", From 2284183ec72df962cf750a10ad6fd6a4967ea218 Mon Sep 17 00:00:00 2001 From: il-s Date: Tue, 30 Nov 2021 09:04:22 +0700 Subject: [PATCH 3/8] reformatted --- fastapi_crudrouter/core/async_sqlalchemy.py | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/fastapi_crudrouter/core/async_sqlalchemy.py b/fastapi_crudrouter/core/async_sqlalchemy.py index 8df31940..6b8241a7 100644 --- a/fastapi_crudrouter/core/async_sqlalchemy.py +++ b/fastapi_crudrouter/core/async_sqlalchemy.py @@ -4,8 +4,6 @@ from . import CRUDGenerator, NOT_FOUND, _utils from ._types import DEPENDENCIES, PAGINATION, PYDANTIC_SCHEMA as SCHEMA -#from fastapi_crudrouter.core._base import CRUDGenerator, NOT_FOUND, _utils -#from fastapi_crudrouter.core._types import DEPENDENCIES, PAGINATION, PYDANTIC_SCHEMA as SCHEMA try: from sqlalchemy.orm import Session @@ -71,7 +69,8 @@ async def route( ) -> List[Model]: skip, limit = pagination.get("skip"), pagination.get("limit") - res = await db.execute(select(self.db_model) + res = await db.execute( + select(self.db_model) .order_by(getattr(self.db_model, self._pk)) .limit(limit) .offset(skip) @@ -79,10 +78,9 @@ async def route( res = res.all() model: Model - db_models: List[Model] = [] # [(row,) for row in res] + db_models: List[Model] = [] for row in res: (model,) = row - # print(model) db_models.append(model) return db_models @@ -95,11 +93,14 @@ async def route( ) -> Model: model: Model try: - (model,) = (await db.execute(select(self.db_model).where(self.db_model.id == item_id))).one() + (model,) = ( + await db.execute( + select(self.db_model).where(self.db_model.id == item_id) + ) + ).one() except NoResultFound: model = None - print([model]) if model: return model else: @@ -149,7 +150,7 @@ async def route( def _delete_all(self, *args: Any, **kwargs: Any) -> Callable[..., List[Model]]: async def route(db: Session = Depends(self.db_func)) -> List[Model]: - await db.execute('delete from '+self.db_model.__tablename__) + await db.execute('delete from ' + self.db_model.__tablename__) await db.commit() return await self._get_all()(db=db, pagination={"skip": 0, "limit": None}) From c09af180bd3dc8182aa6551150aa7dcd12ca63d6 Mon Sep 17 00:00:00 2001 From: il-s Date: Tue, 30 Nov 2021 13:01:28 +0700 Subject: [PATCH 4/8] reformatted 2 --- fastapi_crudrouter/core/async_sqlalchemy.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fastapi_crudrouter/core/async_sqlalchemy.py b/fastapi_crudrouter/core/async_sqlalchemy.py index 6b8241a7..4e0ce079 100644 --- a/fastapi_crudrouter/core/async_sqlalchemy.py +++ b/fastapi_crudrouter/core/async_sqlalchemy.py @@ -150,7 +150,7 @@ async def route( def _delete_all(self, *args: Any, **kwargs: Any) -> Callable[..., List[Model]]: async def route(db: Session = Depends(self.db_func)) -> List[Model]: - await db.execute('delete from ' + self.db_model.__tablename__) + await db.execute("delete from " + self.db_model.__tablename__) await db.commit() return await self._get_all()(db=db, pagination={"skip": 0, "limit": None}) From 424c013795c6497b14b4b4e36a10b8de0d8570fa Mon Sep 17 00:00:00 2001 From: il-s Date: Tue, 30 Nov 2021 22:54:54 +0700 Subject: [PATCH 5/8] rollback --- fastapi_crudrouter/__init__.py | 2 - fastapi_crudrouter/core/__init__.py | 2 - fastapi_crudrouter/core/async_sqlalchemy.py | 169 -------------------- 3 files changed, 173 deletions(-) delete mode 100644 fastapi_crudrouter/core/async_sqlalchemy.py diff --git a/fastapi_crudrouter/__init__.py b/fastapi_crudrouter/__init__.py index 44627ab6..2218903d 100644 --- a/fastapi_crudrouter/__init__.py +++ b/fastapi_crudrouter/__init__.py @@ -4,7 +4,6 @@ MemoryCRUDRouter, OrmarCRUDRouter, SQLAlchemyCRUDRouter, - AsyncSQLAlchemyCRUDRouter, TortoiseCRUDRouter, ) @@ -13,7 +12,6 @@ __all__ = [ "MemoryCRUDRouter", "SQLAlchemyCRUDRouter", - "AsyncSQLAlchemyCRUDRouter", "DatabasesCRUDRouter", "TortoiseCRUDRouter", "OrmarCRUDRouter", diff --git a/fastapi_crudrouter/core/__init__.py b/fastapi_crudrouter/core/__init__.py index d4e7d8ec..68b8947c 100644 --- a/fastapi_crudrouter/core/__init__.py +++ b/fastapi_crudrouter/core/__init__.py @@ -5,7 +5,6 @@ from .mem import MemoryCRUDRouter from .ormar import OrmarCRUDRouter from .sqlalchemy import SQLAlchemyCRUDRouter -from .async_sqlalchemy import AsyncSQLAlchemyCRUDRouter from .tortoise import TortoiseCRUDRouter __all__ = [ @@ -14,7 +13,6 @@ "NOT_FOUND", "MemoryCRUDRouter", "SQLAlchemyCRUDRouter", - "AsyncSQLAlchemyCRUDRouter", "DatabasesCRUDRouter", "TortoiseCRUDRouter", "OrmarCRUDRouter", diff --git a/fastapi_crudrouter/core/async_sqlalchemy.py b/fastapi_crudrouter/core/async_sqlalchemy.py deleted file mode 100644 index 4e0ce079..00000000 --- a/fastapi_crudrouter/core/async_sqlalchemy.py +++ /dev/null @@ -1,169 +0,0 @@ -from typing import Any, Callable, List, Type, Generator, Optional, Union - -from fastapi import Depends, HTTPException - -from . import CRUDGenerator, NOT_FOUND, _utils -from ._types import DEPENDENCIES, PAGINATION, PYDANTIC_SCHEMA as SCHEMA - -try: - from sqlalchemy.orm import Session - from sqlalchemy.ext.declarative import DeclarativeMeta as Model - from sqlalchemy.exc import IntegrityError, NoResultFound - from sqlalchemy.future import select -except ImportError: - Model: Any = None # type: ignore - sqlalchemy_installed = False -else: - sqlalchemy_installed = True - Session = Callable[..., Generator[Session, Any, None]] - - -class AsyncSQLAlchemyCRUDRouter(CRUDGenerator[SCHEMA]): - def __init__( - self, - schema: Type[SCHEMA], - db_model: Model, - db: "Session", - create_schema: Optional[Type[SCHEMA]] = None, - update_schema: Optional[Type[SCHEMA]] = None, - prefix: Optional[str] = None, - tags: Optional[List[str]] = None, - paginate: Optional[int] = None, - get_all_route: Union[bool, DEPENDENCIES] = True, - get_one_route: Union[bool, DEPENDENCIES] = True, - create_route: Union[bool, DEPENDENCIES] = True, - update_route: Union[bool, DEPENDENCIES] = True, - delete_one_route: Union[bool, DEPENDENCIES] = True, - delete_all_route: Union[bool, DEPENDENCIES] = True, - **kwargs: Any - ) -> None: - assert ( - sqlalchemy_installed - ), "SQLAlchemy must be installed to use the SQLAlchemyCRUDRouter." - - self.db_model = db_model - self.db_func = db - self._pk: str = db_model.__table__.primary_key.columns.keys()[0] - self._pk_type: type = _utils.get_pk_type(schema, self._pk) - - super().__init__( - schema=schema, - create_schema=create_schema, - update_schema=update_schema, - prefix=prefix or db_model.__tablename__, - tags=tags, - paginate=paginate, - get_all_route=get_all_route, - get_one_route=get_one_route, - create_route=create_route, - update_route=update_route, - delete_one_route=delete_one_route, - delete_all_route=delete_all_route, - **kwargs - ) - - def _get_all(self, *args: Any, **kwargs: Any) -> Callable[..., List[Model]]: - async def route( - db: Session = Depends(self.db_func), - pagination: PAGINATION = self.pagination, - ) -> List[Model]: - skip, limit = pagination.get("skip"), pagination.get("limit") - - res = await db.execute( - select(self.db_model) - .order_by(getattr(self.db_model, self._pk)) - .limit(limit) - .offset(skip) - ) - res = res.all() - - model: Model - db_models: List[Model] = [] - for row in res: - (model,) = row - db_models.append(model) - - return db_models - - return route - - def _get_one(self, *args: Any, **kwargs: Any) -> Callable[..., Model]: - async def route( - item_id: self._pk_type, db: Session = Depends(self.db_func) # type: ignore - ) -> Model: - model: Model - try: - (model,) = ( - await db.execute( - select(self.db_model).where(self.db_model.id == item_id) - ) - ).one() - except NoResultFound: - model = None - - if model: - return model - else: - raise NOT_FOUND from None - - return route - - def _create(self, *args: Any, **kwargs: Any) -> Callable[..., Model]: - async def route( - model: self.create_schema, # type: ignore - db: Session = Depends(self.db_func), - ) -> Model: - try: - db_model: Model = self.db_model(**model.dict()) - db.add(db_model) - await db.commit() - await db.refresh(db_model) - return db_model - except IntegrityError: - await db.rollback() - raise HTTPException(422, "Key already exists") from None - - return route - - def _update(self, *args: Any, **kwargs: Any) -> Callable[..., Model]: - async def route( - item_id: self._pk_type, # type: ignore - model: self.update_schema, # type: ignore - db: Session = Depends(self.db_func), - ) -> Model: - try: - db_model: Model = await self._get_one()(item_id, db) - - for key, value in model.dict(exclude={self._pk}).items(): - if hasattr(db_model, key): - setattr(db_model, key, value) - - await db.commit() - await db.refresh(db_model) - - return db_model - except IntegrityError as e: - await db.rollback() - self._raise(e) - - return route - - def _delete_all(self, *args: Any, **kwargs: Any) -> Callable[..., List[Model]]: - async def route(db: Session = Depends(self.db_func)) -> List[Model]: - await db.execute("delete from " + self.db_model.__tablename__) - await db.commit() - return await self._get_all()(db=db, pagination={"skip": 0, "limit": None}) - - return route - - def _delete_one(self, *args: Any, **kwargs: Any) -> Callable[..., Model]: - async def route( - item_id: self._pk_type, db: Session = Depends(self.db_func) # type: ignore - ) -> Model: - db_model: Model = await self._get_one()(item_id, db) - await db.delete(db_model) - await db.commit() - - return db_model - - return route From d1650b766bbd08e097e56fb1b7510093ec963440 Mon Sep 17 00:00:00 2001 From: il-s Date: Tue, 30 Nov 2021 23:01:03 +0700 Subject: [PATCH 6/8] Change router to detect async SQLAlchemy mode and execute asynchronously --- fastapi_crudrouter/core/sqlalchemy.py | 125 ++++++++++++++++++++++++-- 1 file changed, 118 insertions(+), 7 deletions(-) diff --git a/fastapi_crudrouter/core/sqlalchemy.py b/fastapi_crudrouter/core/sqlalchemy.py index 58270f34..dc19a7aa 100644 --- a/fastapi_crudrouter/core/sqlalchemy.py +++ b/fastapi_crudrouter/core/sqlalchemy.py @@ -4,11 +4,15 @@ from . import CRUDGenerator, NOT_FOUND, _utils from ._types import DEPENDENCIES, PAGINATION, PYDANTIC_SCHEMA as SCHEMA +import inspect try: from sqlalchemy.orm import Session from sqlalchemy.ext.declarative import DeclarativeMeta as Model - from sqlalchemy.exc import IntegrityError + from sqlalchemy.exc import IntegrityError, NoResultFound + from sqlalchemy import __version__ as sqlalchemy_version + if sqlalchemy_version >= "1.4": + from sqlalchemy.future import select except ImportError: Model = None Session = None @@ -47,6 +51,7 @@ def __init__( self.db_model = db_model self.db_func = db + self.use_async = (inspect.isasyncgenfunction(db) or inspect.isasyncgen(db)) and sqlalchemy_version >= "1.4" # autodetect async mode self._pk: str = db_model.__table__.primary_key.columns.keys()[0] self._pk_type: type = _utils.get_pk_type(schema, self._pk) @@ -82,7 +87,32 @@ def route( ) return db_models - return route + async def async_route( + db: Session = Depends(self.db_func), + pagination: PAGINATION = self.pagination, + ) -> List[Model]: + skip, limit = pagination.get("skip"), pagination.get("limit") + + res = await db.execute( + select(self.db_model) + .order_by(getattr(self.db_model, self._pk)) + .limit(limit) + .offset(skip) + ) + res = res.all() + + model: Model + db_models: List[Model] = [] + for row in res: + (model,) = row + db_models.append(model) + + return db_models + + if self.use_async: + return async_route + else: + return route def _get_one(self, *args: Any, **kwargs: Any) -> CALLABLE: def route( @@ -95,7 +125,28 @@ def route( else: raise NOT_FOUND from None - return route + async def async_route( + item_id: self._pk_type, db: Session = Depends(self.db_func) # type: ignore + ) -> Model: + model: Model + try: + (model,) = ( + await db.execute( + select(self.db_model).where(self.db_model.id == item_id) + ) + ).one() + except NoResultFound: + model = None + + if model: + return model + else: + raise NOT_FOUND from None + + if self.use_async: + return async_route + else: + return route def _create(self, *args: Any, **kwargs: Any) -> CALLABLE: def route( @@ -112,7 +163,24 @@ def route( db.rollback() raise HTTPException(422, "Key already exists") from None - return route + async def async_route( + model: self.create_schema, # type: ignore + db: Session = Depends(self.db_func), + ) -> Model: + try: + db_model: Model = self.db_model(**model.dict()) + db.add(db_model) + await db.commit() + await db.refresh(db_model) + return db_model + except IntegrityError: + await db.rollback() + raise HTTPException(422, "Key already exists") from None + + if self.use_async: + return async_route + else: + return route def _update(self, *args: Any, **kwargs: Any) -> CALLABLE: def route( @@ -135,7 +203,30 @@ def route( db.rollback() self._raise(e) - return route + async def async_route( + item_id: self._pk_type, # type: ignore + model: self.update_schema, # type: ignore + db: Session = Depends(self.db_func), + ) -> Model: + try: + db_model: Model = await self._get_one()(item_id, db) + + for key, value in model.dict(exclude={self._pk}).items(): + if hasattr(db_model, key): + setattr(db_model, key, value) + + await db.commit() + await db.refresh(db_model) + + return db_model + except IntegrityError as e: + await db.rollback() + self._raise(e) + + if self.use_async: + return async_route + else: + return route def _delete_all(self, *args: Any, **kwargs: Any) -> CALLABLE_LIST: def route(db: Session = Depends(self.db_func)) -> List[Model]: @@ -144,7 +235,15 @@ def route(db: Session = Depends(self.db_func)) -> List[Model]: return self._get_all()(db=db, pagination={"skip": 0, "limit": None}) - return route + async def async_route(db: Session = Depends(self.db_func)) -> List[Model]: + await db.execute("delete from " + self.db_model.__tablename__) + await db.commit() + return await self._get_all()(db=db, pagination={"skip": 0, "limit": None}) + + if self.use_async: + return async_route + else: + return route def _delete_one(self, *args: Any, **kwargs: Any) -> CALLABLE: def route( @@ -156,4 +255,16 @@ def route( return db_model - return route + async def async_route( + item_id: self._pk_type, db: Session = Depends(self.db_func) # type: ignore + ) -> Model: + db_model: Model = await self._get_one()(item_id, db) + await db.delete(db_model) + await db.commit() + + return db_model + + if self.use_async: + return async_route + else: + return route From 8e4881a520caaf2667e1dd1217d3ee04309c0ab7 Mon Sep 17 00:00:00 2001 From: il-s Date: Sun, 5 Dec 2021 12:36:33 +0700 Subject: [PATCH 7/8] Added use_async parameter to specify the mode of work (true: async; false: not; None: autodetect) --- fastapi_crudrouter/core/sqlalchemy.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/fastapi_crudrouter/core/sqlalchemy.py b/fastapi_crudrouter/core/sqlalchemy.py index dc19a7aa..909d9b92 100644 --- a/fastapi_crudrouter/core/sqlalchemy.py +++ b/fastapi_crudrouter/core/sqlalchemy.py @@ -43,6 +43,7 @@ def __init__( update_route: Union[bool, DEPENDENCIES] = True, delete_one_route: Union[bool, DEPENDENCIES] = True, delete_all_route: Union[bool, DEPENDENCIES] = True, + use_async: Optional[bool] = None, # if not set, try autidetect **kwargs: Any ) -> None: assert ( @@ -51,7 +52,10 @@ def __init__( self.db_model = db_model self.db_func = db - self.use_async = (inspect.isasyncgenfunction(db) or inspect.isasyncgen(db)) and sqlalchemy_version >= "1.4" # autodetect async mode + if use_async == None: + self.use_async = (inspect.isasyncgenfunction(db) or inspect.isasyncgen(db)) and sqlalchemy_version >= "1.4" # autodetect async mode + else: + self.use_async = use_async self._pk: str = db_model.__table__.primary_key.columns.keys()[0] self._pk_type: type = _utils.get_pk_type(schema, self._pk) From 0930fd16743dfc6016929b1ddfac1cb274f5d4b0 Mon Sep 17 00:00:00 2001 From: il-s Date: Sun, 5 Dec 2021 22:17:53 +0700 Subject: [PATCH 8/8] reformat 2 --- fastapi_crudrouter/core/sqlalchemy.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/fastapi_crudrouter/core/sqlalchemy.py b/fastapi_crudrouter/core/sqlalchemy.py index 909d9b92..04552cdc 100644 --- a/fastapi_crudrouter/core/sqlalchemy.py +++ b/fastapi_crudrouter/core/sqlalchemy.py @@ -11,6 +11,7 @@ from sqlalchemy.ext.declarative import DeclarativeMeta as Model from sqlalchemy.exc import IntegrityError, NoResultFound from sqlalchemy import __version__ as sqlalchemy_version + if sqlalchemy_version >= "1.4": from sqlalchemy.future import select except ImportError: @@ -43,7 +44,7 @@ def __init__( update_route: Union[bool, DEPENDENCIES] = True, delete_one_route: Union[bool, DEPENDENCIES] = True, delete_all_route: Union[bool, DEPENDENCIES] = True, - use_async: Optional[bool] = None, # if not set, try autidetect + use_async: Optional[bool] = None, # if not set, try autodetect **kwargs: Any ) -> None: assert ( @@ -53,7 +54,9 @@ def __init__( self.db_model = db_model self.db_func = db if use_async == None: - self.use_async = (inspect.isasyncgenfunction(db) or inspect.isasyncgen(db)) and sqlalchemy_version >= "1.4" # autodetect async mode + self.use_async = ( + inspect.isasyncgenfunction(db) or inspect.isasyncgen(db) + ) and sqlalchemy_version >= "1.4" # autodetect async mode else: self.use_async = use_async self._pk: str = db_model.__table__.primary_key.columns.keys()[0]