Work on CRUD POST and PATCH related.

This commit is contained in:
Scott Idem
2024-03-08 18:10:10 -05:00
parent eff1da6644
commit 14c6cb8bc0

View File

@@ -500,7 +500,7 @@ async def get_obj(
# ### BEGIN ### API CRUD ### patch_obj() ###
# Updated 2022-11-29
# Updated 2024-03-08
@router.patch('/{obj_type_l1}/{obj_id}')
@router.patch('/{obj_type_l1}/{obj_type_l2}/{obj_id}')
@router.patch('/{obj_type_l1}/{obj_type_l2}/{obj_type_l3}/{obj_id}')
@@ -516,7 +516,9 @@ async def patch_obj(
# for_obj_type: Optional[str] = Query(None, max_length=50),
# for_obj_id: Optional[str] = Query(None, max_length=22),
# return_obj: Optional[bool] = True, # I am not sure how to make this work yet. -2024-03-07
# The view name will be prefixed with "v_" and must be a valid view name based on the object type name from the URL. obj_type_l1, obj_type_l2, obj_type_l3 combined below as obj_name
return_obj: Optional[bool] = True, # I am not sure how to make this work yet. -2024-03-08
obj_v_name: Optional[str] = None, # Use view name to help return the object type. -2024-03-08
commons: Common_Route_Params = Depends(common_route_params),
):
@@ -597,7 +599,7 @@ async def patch_obj(
exclude = obj_type_li[obj_name].get('exclude_for_db')
# ### SECTION ### Secondary data validation
# obj_id_random = obj_id # This might need to be used later for the response data
obj_id_random = obj_id # This might need to be used later for the response data
if obj_id := redis_lookup_id_random(record_id_random=obj_id, table_name=table_name): pass
else: return mk_resp(data=None, status_code=404, response=commons.response, status_message='The object ID was invalid or not found.')
@@ -636,8 +638,11 @@ async def patch_obj(
resp_data = {}
resp_data['table_name'] = table_name
resp_data['request_data'] = obj_dict
resp_data['obj_id'] = obj_id
resp_data['obj_id_random'] = obj_id_random
return mk_resp(data=resp_data, response=commons.response) #, details=debug_data)
# Comment out the following line if you do not want to allo for returning the updated data.
# return mk_resp(data=resp_data, response=commons.response) #, details=debug_data)
elif sql_result == None:
log.info('The record was probably not found to be updated.')
log.debug(sql_result)
@@ -649,18 +654,45 @@ async def patch_obj(
# ### SECTION ### Return successful results
# if return_obj:
# data_store_obj = load_data_store_obj(
# data_store_id = data_store_id,
# )
# resp_data = data_store_obj
# return mk_resp(data=resp_data, response=commons.response) #, details=debug_data)
# NOTE: obj_id was found and verified above
# New: 2024-03-08
if return_obj:
if obj_v_name:
# We should add a sanity check here to make sure the view name is valid first.
table_name = f'v_{obj_v_name}'
# Remove an extra "v_" if it is there.
if table_name.startswith('v_v_'):
table_name = table_name[2:]
# We can do more later... like check against an allowed list of view names per Aether object type
else:
# Use the table_name as a backup option? This should be safe since it is also passed through the model.
table_name = obj_type_li[obj_name]['table_name']
base_name = obj_type_li[obj_name]['base_name']
if sql_select_result := sql_select(table_name=table_name, record_id=obj_id):
log.debug(sql_select_result)
log.debug(base_name)
resp_data = base_name(**sql_select_result).dict(by_alias=True, exclude_unset=commons.exclude_unset)
log.debug(resp_data)
log.info(f'Returning object model {base_name} from table_name {table_name}; obj_id; obj_id_random={obj_id_random}) using PATCH data')
return mk_resp(data=resp_data, response=commons.response)
else:
log.debug(sql_select_result)
status_message = f'The record was not found in table_name={table_name} used for the SQL SELECT query. This may be a SQL VIEW and may be because the SQL VIEW needs to be created or updated.'
return mk_resp(data=False, status_code=404, response=commons.response, status_message=status_message)
log.info(f'Returning IDs (obj_id, obj_id_random={obj_id_random}) using PATCH data')
return mk_resp(data=resp_data, response=commons.response) #, details=debug_data)
# ### END ### API CRUD ### patch_obj() ###
# ### BEGIN ### API CRUD ### post_obj() ###
# Updated 2022-11-29
# Updated 2024-03-08
@router.post('/{obj_type_l1}')
@router.post('/{obj_type_l1}/{obj_type_l2}')
@router.post('/{obj_type_l1}/{obj_type_l2}/{obj_type_l3}')
@@ -673,10 +705,12 @@ async def post_obj(
run_safety_check: bool = True,
# The view name will be prefixed with "v_" and must be a valid view name based on the object type name from the URL. obj_type_l1, obj_type_l2, obj_type_l3 combined below as obj_name
# for_obj_type: Optional[str] = Query(None, max_length=50),
# for_obj_id: Optional[str] = Query(None, max_length=22),
return_obj: bool = True,
return_obj: Optional[bool] = True,
obj_v_name: Optional[str] = None, # Use view name to help return the object type. -2024-03-08
commons: Common_Route_Params = Depends(common_route_params),
):
@@ -753,8 +787,37 @@ async def post_obj(
log.warning('We should not be here')
return mk_resp(data=False, status_code=400, response=commons.response)
table_name = obj_type_li[obj_name].get('tbl_name_update')
table_name_select = obj_type_li[obj_name].get('table_name')
# ### SECTION ### Figure out the table_name to use
# Updated: 2024-03-08
view_name = None # This is the view name to use for the SQL SELECT query
if obj_v_name:
# We should add a sanity check here to make sure the view name is valid first.
view_name = f'v_{obj_v_name}'
# Remove an extra "v_" if it is there.
if view_name.startswith('v_v_'):
view_name = view_name[2:]
# We can do more later... like check against an allowed list of view names per Aether object type
elif obj_type_li[obj_name].get('table_name'):
# Use the table_name as a backup option? This should be safe.
view_name = obj_type_li[obj_name].get('table_name')
elif obj_type_li[obj_name].get('table_name_alt'):
view_name = obj_type_li[obj_name].get('table_name_alt')
elif obj_type_li[obj_name].get('tbl_name_update'):
view_name = obj_type_li[obj_name].get('tbl_name_update')
else:
log.error('The table_name was not found. This is a critical error. Returning False.')
return mk_resp(data=False, status_code=400, response=commons.response, status_message='The table_name was not found. This is a critical error.')
table_name = None # This is the table name to use for the SQL INSERT or UPDATE
if obj_type_li[obj_name].get('tbl_name_update'):
table_name = obj_type_li[obj_name].get('tbl_name_update')
elif obj_type_li[obj_name].get('table_name'):
table_name = obj_type_li[obj_name].get('table_name')
# This should be a view in most cases.
table_name_select = view_name
exclude = obj_type_li[obj_name].get('exclude_for_db')
@@ -803,8 +866,11 @@ async def post_obj(
obj_id_random = get_id_random(record_id=obj_id, table_name=table_name)
resp_data['obj_id_random'] = obj_id_random
# NOTE: obj_id was found and verified above
# Updated: 2024-03-08
if return_obj:
log.info('Returning object created from POST data')
# This is the more or less the same as what is done in the patch_obj() endpoint.
if sql_select_result := sql_select(table_name=table_name_select, record_id=obj_id):
log.debug(sql_select_result)
@@ -814,6 +880,7 @@ async def post_obj(
log.debug(resp_data)
log.info(f'Returning object model ({base_name}; obj_id; obj_id_random={obj_id_random}) from POST data')
return mk_resp(data=resp_data, response=commons.response)
else:
log.debug(sql_select_result)
@@ -828,7 +895,7 @@ async def post_obj(
else:
log.info('Something unexpected happened while trying to runt he SQL UPDATE. The fields or field values passed may not be valid for the table and or model.')
log.debug(sql_result)
return mk_resp(data=False, status_code=400, status_message='Something unexpected happened while trying to runt he SQL UPDATE. The fields or field values passed may not be valid for the table and or model.', response=commons.response)
return mk_resp(data=False, status_code=400, status_message='Something unexpected happened while trying to run the SQL UPDATE. The fields or field values passed may not be valid for the table and or model.', response=commons.response)
# ### END ### API CRUD ### post_obj() ###