Skip to content

Commit 8058dfb

Browse files
committed
add foreign tree api
1 parent 2ab2072 commit 8058dfb

8 files changed

Lines changed: 358 additions & 164 deletions

File tree

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,5 @@ tests/htmlcov
55
/pyproject.toml
66
*.pyc
77
workspace.xml
8+
*.iml
9+
*.xml

src/fastapi_quickcrud/crud_router.py

Lines changed: 49 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -109,18 +109,19 @@ def get_transaction_session():
109109

110110
if async_mode is None:
111111
async_mode = inspect.isasyncgen(db_session())
112-
112+
113113
if sql_type is None:
114114
async def async_runner(f):
115115
return [i.bind.name async for i in f()]
116+
116117
try:
117118
if async_mode:
118119
sql_type, = asyncio.get_event_loop().run_until_complete(async_runner(db_session))
119120
else:
120121
sql_type, = [i.bind.name for i in db_session()]
121122
except Exception:
122123
raise RuntimeError("Some unknown problem occurred error, maybe you are uvicorn.run with reload=True. "
123-
"Try declaring sql_type for crud_router_builder yourself using from fastapi_quickcrud.misc.type import SqlType")
124+
"Try declaring sql_type for crud_router_builder yourself using from fastapi_quickcrud.misc.type import SqlType")
124125

125126
if not crud_methods and NO_PRIMARY_KEY == False:
126127
crud_methods = CrudMethods.get_declarative_model_full_crud_method()
@@ -145,6 +146,7 @@ async def async_runner(f):
145146
crud_methods=crud_methods,
146147
exclude_columns=exclude_columns,
147148
sql_type=sql_type,
149+
foreign_include=foreign_include,
148150
exclude_primary_key=NO_PRIMARY_KEY)
149151

150152
foreign_table_mapping = {db_model.__tablename__: db_model}
@@ -377,6 +379,48 @@ def put_many_api(request_response_model: dict, dependencies):
377379
async_mode=async_mode,
378380
response_model=_response_model)
379381

382+
def find_one_foreign_tree_api(request_response_model: dict, dependencies):
383+
_foreign_list_model = request_response_model.get('foreignListModel', None)
384+
for i in _foreign_list_model:
385+
_request_query_model = i["request_query_model"]
386+
_response_model = i["response_model"]
387+
_path = i["path"]
388+
_function_name = i["function_name"]
389+
request_url_param_model = i["primary_key_dataclass_model"]
390+
routes_source.find_one_foreign_tree(path=_path,
391+
request_query_model=_request_query_model,
392+
response_model=_response_model,
393+
request_url_param_model=request_url_param_model,
394+
db_session=db_session,
395+
query_service=crud_service,
396+
parsing_service=result_parser,
397+
execute_service=execute_service,
398+
dependencies=dependencies,
399+
api=api,
400+
function_name=_function_name,
401+
async_mode=async_mode)
402+
403+
def find_many_foreign_tree_api(request_response_model: dict, dependencies):
404+
_foreign_list_model = request_response_model.get('foreignListModel', None)
405+
for i in _foreign_list_model:
406+
_request_query_model = i["request_query_model"]
407+
_response_model = i["response_model"]
408+
_path = i["path"]
409+
_function_name = i["function_name"]
410+
request_url_param_model = i["primary_key_dataclass_model"]
411+
routes_source.find_many_foreign_tree(path=_path,
412+
request_query_model=_request_query_model,
413+
response_model=_response_model,
414+
request_url_param_model=request_url_param_model,
415+
db_session=db_session,
416+
query_service=crud_service,
417+
parsing_service=result_parser,
418+
execute_service=execute_service,
419+
dependencies=dependencies,
420+
api=api,
421+
async_mode=async_mode,
422+
function_name=_function_name)
423+
380424
api_register = {
381425
CrudMethods.FIND_ONE.value: find_one_api,
382426
CrudMethods.FIND_MANY.value: find_many_api,
@@ -390,7 +434,9 @@ def put_many_api(request_response_model: dict, dependencies):
390434
CrudMethods.PATCH_ONE.value: patch_one_api,
391435
CrudMethods.PATCH_MANY.value: patch_many_api,
392436
CrudMethods.UPDATE_ONE.value: put_one_api,
393-
CrudMethods.UPDATE_MANY.value: put_many_api
437+
CrudMethods.UPDATE_MANY.value: put_many_api,
438+
CrudMethods.FIND_ONE_WITH_FOREIGN_TREE.value: find_one_foreign_tree_api,
439+
CrudMethods.FIND_MANY_WITH_FOREIGN_TREE.value: find_many_foreign_tree_api
394440
}
395441
api = APIRouter(**router_kwargs)
396442

src/fastapi_quickcrud/misc/abstract_route.py

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -737,6 +737,122 @@ def entire_update_many_by_query(
737737
# fastapi_response=response,
738738
# session=session)
739739

740+
@classmethod
741+
def find_one_foreign_tree(cls, api, *,
742+
query_service,
743+
parsing_service,
744+
execute_service,
745+
async_mode,
746+
path,
747+
response_model,
748+
dependencies,
749+
request_query_model,
750+
request_url_param_model,
751+
function_name,
752+
db_session):
753+
754+
if async_mode:
755+
@api.get(path, dependencies=dependencies, response_model=response_model, name=function_name)
756+
async def async_get_one_with_foreign_tree(response: Response,
757+
request: Request,
758+
url_param=Depends(request_url_param_model),
759+
query=Depends(request_query_model),
760+
session=Depends(
761+
db_session)
762+
):
763+
target_model = request.url.path.split("/")[-2]
764+
join = query.__dict__.pop('join_foreign_table', None)
765+
stmt = query_service.get_many_with_foreign_pk(query=query.__dict__, join_mode=join,
766+
target_model=target_model)
767+
768+
query_result = await execute_service.async_execute(session, stmt)
769+
770+
parsed_response = await parsing_service.async_find_one(response_model=response_model,
771+
sql_execute_result=query_result,
772+
fastapi_response=response,
773+
join_mode=join,
774+
session=session)
775+
return parsed_response
776+
else:
777+
@api.get(path, dependencies=dependencies, response_model=response_model, name=function_name)
778+
def get_one_with_foreign_tree(response: Response,
779+
request: Request,
780+
url_param=Depends(request_url_param_model),
781+
query=Depends(request_query_model),
782+
session=Depends(
783+
db_session)
784+
):
785+
target_model = request.url.path.split("/")[-2]
786+
join = query.__dict__.pop('join_foreign_table', None)
787+
788+
stmt = query_service.get_many_with_foreign_pk(query=query.__dict__, join_mode=join,
789+
target_model=target_model)
790+
query_result = execute_service.execute(session, stmt)
791+
parsed_response = parsing_service.find_one(response_model=response_model,
792+
sql_execute_result=query_result,
793+
fastapi_response=response,
794+
join_mode=join,
795+
session=session)
796+
return parsed_response
797+
798+
@classmethod
799+
def find_many_foreign_tree(cls, api, *,
800+
query_service,
801+
parsing_service,
802+
execute_service,
803+
async_mode,
804+
path,
805+
response_model,
806+
dependencies,
807+
request_query_model,
808+
request_url_param_model,
809+
function_name,
810+
db_session):
811+
812+
if async_mode:
813+
@api.get(path, dependencies=dependencies, response_model=response_model, name=function_name)
814+
async def async_get_many_with_foreign_tree(response: Response,
815+
request: Request,
816+
url_param=Depends(request_url_param_model),
817+
query=Depends(request_query_model),
818+
session=Depends(
819+
db_session)
820+
):
821+
target_model = request.url.path.split("/")[-1]
822+
join = query.__dict__.pop('join_foreign_table', None)
823+
stmt = query_service.get_many(query=query.__dict__, join_mode=join, abstract_param=url_param,
824+
target_model=target_model)
825+
826+
query_result = await execute_service.async_execute(session, stmt)
827+
828+
parsed_response = await parsing_service.async_find_many(response_model=response_model,
829+
sql_execute_result=query_result,
830+
fastapi_response=response,
831+
join_mode=join,
832+
session=session)
833+
return parsed_response
834+
else:
835+
@api.get(path, dependencies=dependencies, response_model=response_model, name=function_name)
836+
def get_many_with_foreign_tree(response: Response,
837+
request: Request,
838+
url_param=Depends(request_url_param_model),
839+
query=Depends(request_query_model),
840+
session=Depends(
841+
db_session)
842+
):
843+
target_model = request.url.path.split("/")[-1]
844+
join = query.__dict__.pop('join_foreign_table', None)
845+
stmt = query_service.get_many(query=query.__dict__, join_mode=join, abstract_param=url_param.__dict__,
846+
target_model=target_model)
847+
query_result = execute_service.execute(session, stmt)
848+
parsed_response = parsing_service.find_many(response_model=response_model,
849+
sql_execute_result=query_result,
850+
fastapi_response=response,
851+
join_mode=join,
852+
session=session)
853+
854+
return parsed_response
855+
740856

741857
class SQLAlchemyPGSQLRouteSource(SQLAlchemyGeneralSQLBaseRouteSource):
742858
'''

src/fastapi_quickcrud/misc/crud_model.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ class RequestResponseModel(BaseModel):
1919
jsonRequestFieldModel: Optional[ModelMetaclass]
2020
jsonbRequestFieldModel: Optional[ModelMetaclass]
2121
arrayRequestFieldModel: Optional[ModelMetaclass]
22+
foreignListModel: Optional[List[dict]]
2223

2324

2425
class CRUDModel(BaseModel):
@@ -27,6 +28,7 @@ class CRUDModel(BaseModel):
2728
PUT: Optional[Dict[CrudMethods, RequestResponseModel]]
2829
PATCH: Optional[Dict[CrudMethods, RequestResponseModel]]
2930
DELETE: Optional[Dict[CrudMethods, RequestResponseModel]]
31+
FIND_MANY_WITH_FOREIGN_TREE: Optional[Dict[CrudMethods, RequestResponseModel]]
3032
PRIMARY_KEY_NAME: Optional[str]
3133
UNIQUE_LIST: Optional[List[str]]
3234

@@ -43,4 +45,3 @@ def get_model_by_request_method(self, request_method):
4345
f'make sure the CRUDModel contains this request method')
4446
_ = available_methods[request_method]
4547
return _
46-

0 commit comments

Comments
 (0)