Skip to content

Commit 4fdc544

Browse files
committed
fix use case
1 parent 3ba8f8e commit 4fdc544

5 files changed

Lines changed: 33 additions & 134 deletions

File tree

src/fastapi_quickcrud/crud_router.py

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
from .misc.crud_model import CRUDModel
2424
from .misc.memory_sql import async_memory_db, sync_memory_db
2525
from .misc.type import CrudMethods, SqlType
26+
from .misc.utils import convert_table_to_model
2627

2728
CRUDModelType = TypeVar("CRUDModelType", bound=BaseModel)
2829
CompulsoryQueryModelType = TypeVar("CompulsoryQueryModelType", bound=BaseModel)
@@ -92,23 +93,7 @@ def get_transaction_session():
9293
"""
9394
NO_PRIMARY_KEY = False
9495

95-
if isinstance(db_model, Table):
96-
db_name = str(db_model.fullname)
97-
table_dict = {'__table__': db_model,
98-
'__tablename__': db_name}
99-
100-
if not db_model.primary_key:
101-
table_dict['__mapper_args__'] = {
102-
"primary_key": [i for i in db_model._columns]
103-
}
104-
NO_PRIMARY_KEY = True
105-
106-
for i in db_model.c:
107-
col, = i.expression.base_columns
108-
table_dict[str(i.key)] = col
109-
110-
tmp = type(f'{db_name}DeclarativeBaseClass', (declarative_base(),), table_dict)
111-
db_model = tmp
96+
db_model = convert_table_to_model(db_model)
11297

11398
constraints = db_model.__table__.constraints
11499

src/fastapi_quickcrud/misc/utils.py

Lines changed: 24 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
or_, \
99
BinaryExpression
1010

11+
from sqlalchemy.sql.schema import Table
1112
from .crud_model import RequestResponseModel, CRUDModel
1213
from .exceptions import QueryOperatorNotFound, PrimaryMissing, UnknownColumn
1314
from .schema_builder import ApiParameterSchemaBuilder
@@ -31,7 +32,8 @@
3132
'find_query_builder',
3233
'Base',
3334
'clean_input_fields',
34-
'group_find_many_join']
35+
'group_find_many_join',
36+
'convert_table_to_model']
3537

3638
unsupported_data_types = ["BLOB"]
3739
partial_supported_data_types = ["INTERVAL", "JSON", "JSONB"]
@@ -94,101 +96,15 @@ def find_query_builder(param: dict, model: Base) -> List[Union[BinaryExpression]
9496
class OrmConfig(BaseConfig):
9597
orm_mode = True
9698

97-
98-
# def sqlalchemy_table_to_pydantic(db_model: Type, *, crud_methods: List[CrudMethods],
99-
# exclude_columns: List[str] = None) -> CRUDModel:
100-
# if exclude_columns is None:
101-
# exclude_columns = []
102-
# request_response_mode_set = {}
103-
# model_builder = ApiParameterSchemaBuilder_(db_model,
104-
# exclude_column=exclude_columns)
105-
# REQUIRE_PRIMARY_KEY_CRUD_METHOD = [CrudMethods.DELETE_ONE.value,
106-
# CrudMethods.FIND_ONE.value,
107-
# CrudMethods.PATCH_ONE.value,
108-
# CrudMethods.POST_REDIRECT_GET.value,
109-
# CrudMethods.UPDATE_ONE.value]
110-
# for crud_method in crud_methods:
111-
# request_url_param_model = None
112-
# request_body_model = None
113-
# response_model = None
114-
# request_query_model = None
115-
# if crud_method.value in REQUIRE_PRIMARY_KEY_CRUD_METHOD and not model_builder.primary_key_str:
116-
# raise PrimaryMissing(f"The generation of this API [{crud_method.value}] requires a primary key")
117-
# if crud_method.value == CrudMethods.UPSERT_ONE.value:
118-
# request_query_model, \
119-
# request_body_model, \
120-
# response_model = model_builder.create_one()
121-
# elif crud_method.value == CrudMethods.UPSERT_MANY.value:
122-
# request_query_model, \
123-
# request_body_model, \
124-
# response_model = model_builder.create_many()
125-
# elif crud_method.value == CrudMethods.DELETE_ONE.value:
126-
# request_url_param_model, \
127-
# request_query_model, \
128-
# request_body_model, \
129-
# response_model = model_builder.delete_one()
130-
# elif crud_method.value == CrudMethods.DELETE_MANY.value:
131-
# request_url_param_model, \
132-
# request_query_model, \
133-
# request_body_model, \
134-
# response_model = model_builder.delete_many()
135-
# elif crud_method.value == CrudMethods.FIND_ONE.value:
136-
# request_url_param_model, \
137-
# request_query_model, \
138-
# request_body_model, \
139-
# response_model = model_builder.find_one()
140-
# elif crud_method.value == CrudMethods.FIND_MANY.value:
141-
# request_query_model, \
142-
# request_body_model, \
143-
# response_model = model_builder.find_many()
144-
# elif crud_method.value == CrudMethods.POST_REDIRECT_GET.value:
145-
# request_query_model, \
146-
# request_body_model, \
147-
# response_model = model_builder.post_redirect_get()
148-
# elif crud_method.value == CrudMethods.PATCH_ONE.value:
149-
# request_url_param_model, \
150-
# request_query_model, \
151-
# request_body_model, \
152-
# response_model = model_builder.patch()
153-
# elif crud_method.value == CrudMethods.UPDATE_ONE.value:
154-
# request_url_param_model, \
155-
# request_query_model, \
156-
# request_body_model, \
157-
# response_model = model_builder.update_one()
158-
# elif crud_method.value == CrudMethods.UPDATE_MANY.value:
159-
# request_url_param_model, \
160-
# request_query_model, \
161-
# request_body_model, \
162-
# response_model = model_builder.update_many()
163-
# elif crud_method.value == CrudMethods.PATCH_MANY.value:
164-
# request_url_param_model, \
165-
# request_query_model, \
166-
# request_body_model, \
167-
# response_model = model_builder.patch_many()
168-
#
169-
# request_response_models = {'requestBodyModel': request_body_model,
170-
# 'responseModel': response_model,
171-
# 'requestQueryModel': request_query_model,
172-
# 'requestUrlParamModel': request_url_param_model}
173-
# request_response_model = RequestResponseModel(**request_response_models)
174-
# request_method = CRUDRequestMapping.get_request_method_by_crud_method(crud_method.value).value
175-
# if request_method not in request_response_mode_set:
176-
# request_response_mode_set[request_method] = {}
177-
# request_response_mode_set[request_method][crud_method.value] = request_response_model
178-
# return CRUDModel(
179-
# **{**request_response_mode_set,
180-
# **{"PRIMARY_KEY_NAME": model_builder.primary_key_str,
181-
# "UNIQUE_LIST": model_builder.unique_fields}})
182-
183-
184-
18599
def sqlalchemy_to_pydantic(
186100
db_model: Type, *,
187101
crud_methods: List[CrudMethods],
188102
sql_type: str = SqlType.postgresql,
189103
exclude_columns: List[str] = None,
190104
constraints = None,
191105
exclude_primary_key=False) -> CRUDModel:
106+
107+
db_model = convert_table_to_model(db_model)
192108
if exclude_columns is None:
193109
exclude_columns = []
194110
request_response_mode_set = {}
@@ -407,3 +323,22 @@ def group_by_foreign_key(item):
407323
result = {**i, **response}
408324
response_list.append(result)
409325
return response_list
326+
327+
def convert_table_to_model(db_model):
328+
if not isinstance(db_model, Table):
329+
return db_model
330+
db_name = str(db_model.fullname)
331+
table_dict = {'__table__': db_model,
332+
'__tablename__': db_name}
333+
334+
if not db_model.primary_key:
335+
table_dict['__mapper_args__'] = {
336+
"primary_key": [i for i in db_model._columns]
337+
}
338+
NO_PRIMARY_KEY = True
339+
340+
for i in db_model.c:
341+
col, = i.expression.base_columns
342+
table_dict[str(i.key)] = col
343+
344+
return type(f'{db_name}DeclarativeBaseClass', (declarative_base(),), table_dict)

tutorial/relationship/many_to_many.py

Lines changed: 4 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -4,26 +4,13 @@
44

55
from fastapi_quickcrud import CrudMethods
66
from fastapi_quickcrud import crud_router_builder
7-
from fastapi_quickcrud import sqlalchemy_table_to_pydantic
87
from fastapi_quickcrud import sqlalchemy_to_pydantic
98

109
app = FastAPI()
1110

1211
Base = declarative_base()
1312
metadata = Base.metadata
1413

15-
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
16-
17-
engine = create_async_engine('postgresql+asyncpg://postgres:1234@127.0.0.1:5432/postgres', future=True, echo=True,
18-
pool_use_lifo=True, pool_pre_ping=True, pool_recycle=7200)
19-
async_session = sessionmaker(bind=engine, class_=AsyncSession)
20-
21-
22-
async def get_transaction_session() -> AsyncSession:
23-
async with async_session() as session:
24-
async with session.begin():
25-
yield session
26-
2714

2815
from sqlalchemy import CHAR, Column, ForeignKey, Integer, Table
2916
from sqlalchemy.orm import relationship
@@ -50,13 +37,8 @@ class Child(Base):
5037
name = Column(CHAR, nullable=True)
5138

5239

53-
@app.on_event("startup")
54-
async def startup_event():
55-
async with engine.begin() as conn:
56-
await conn.run_sync(Base.metadata.create_all)
57-
5840

59-
user_model_m2m = sqlalchemy_table_to_pydantic(db_model=association_table,
41+
user_model_m2m = sqlalchemy_to_pydantic(db_model=association_table,
6042
crud_methods=[
6143
CrudMethods.FIND_MANY,
6244
CrudMethods.UPSERT_ONE,
@@ -92,24 +74,21 @@ async def startup_event():
9274
],
9375
exclude_columns=[])
9476

95-
crud_route_1 = crud_router_builder(db_session=get_transaction_session,
96-
crud_models=user_model_set,
77+
crud_route_1 = crud_router_builder(crud_models=user_model_set,
9778
db_model=Parent,
9879
prefix="/Parent",
9980
dependencies=[],
10081
async_mode=True,
10182
tags=["Parent"]
10283
)
103-
crud_route_3 = crud_router_builder(db_session=get_transaction_session,
104-
crud_models=user_model_m2m,
84+
crud_route_3 = crud_router_builder(crud_models=user_model_m2m,
10585
db_model=association_table,
10686
prefix="/Parent2child",
10787
dependencies=[],
10888
async_mode=True,
10989
tags=["m2m"]
11090
)
111-
crud_route_2 = crud_router_builder(db_session=get_transaction_session,
112-
crud_models=friend_model_set,
91+
crud_route_2 = crud_router_builder(crud_models=friend_model_set,
11392
db_model=Child,
11493
async_mode=True,
11594
prefix="/Child",

tutorial/relationship/one_to_many.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010

1111
from fastapi_quickcrud import CrudMethods
1212
from fastapi_quickcrud import crud_router_builder
13-
from fastapi_quickcrud import sqlalchemy_table_to_pydantic
1413
from fastapi_quickcrud import sqlalchemy_to_pydantic
1514

1615
app = FastAPI()

tutorial/sample.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
from fastapi import FastAPI
22
from sqlalchemy import *
33
from sqlalchemy.orm import *
4-
from fastapi_quickcrud import crud_router_builder
54
from fastapi_quickcrud.crud_router import generic_sql_crud_router_builder
65

76
Base = declarative_base()
@@ -32,10 +31,12 @@ class Child(Base):
3231
tags=["child"]
3332
)
3433

35-
3634
app = FastAPI()
3735
[app.include_router(i) for i in [crud_route_parent, crud_route_child]]
3836

37+
@app.get("/", tags=["child"])
38+
async def root():
39+
return {"message": "Hello World"}
3940

4041
import uvicorn
4142
uvicorn.run(app, host="0.0.0.0", port=8002, debug=False)

0 commit comments

Comments
 (0)