Sync Insert for unknown fields now drops the unknown fields, and proceeds.
This commit is contained in:
parent
85db628921
commit
90e7ee8da5
1 changed files with 36 additions and 43 deletions
|
|
@ -51,30 +51,24 @@ def _wrapped_insert(model_class: Type, data_list: dict | list, session: Session,
|
|||
|
||||
logger.info(f"Starting insert for {model_class.__name__}")
|
||||
|
||||
try:
|
||||
for each_json in data_list:
|
||||
instance = model_class(**each_json)
|
||||
session.add(instance)
|
||||
session.commit() # Commits both delete + inserts atomically
|
||||
logger.info("Finished wrapped insert!")
|
||||
return DatabaseOperation(valid=True)
|
||||
|
||||
except TypeError as e:
|
||||
"""
|
||||
This is triggered when an Old client was sent unknown fields from the API in the JSON,
|
||||
And it's handled inside the wrapped function because it needs access to the variables used.
|
||||
"""
|
||||
session.rollback()
|
||||
|
||||
# Get valid field names upfront
|
||||
valid_fields = {col.name for col in model_class.__table__.columns}
|
||||
filtered_data_list = [
|
||||
{k: v for k, v in each_json.items() if k in valid_fields}
|
||||
for each_json in data_list
|
||||
]
|
||||
|
||||
dropped_fields = set().union(*(set(d.keys()) - valid_fields for d in data_list))
|
||||
if dropped_fields:
|
||||
logger.warning(f"Old Client Dropped unknown fields: {dropped_fields}")
|
||||
# Filter data proactively
|
||||
filtered_data_list = []
|
||||
all_dropped_fields = set()
|
||||
|
||||
for each_json in data_list:
|
||||
filtered_json = {k: v for k, v in each_json.items() if k in valid_fields}
|
||||
filtered_data_list.append(filtered_json)
|
||||
|
||||
# Track dropped fields
|
||||
dropped = set(each_json.keys()) - valid_fields
|
||||
all_dropped_fields.update(dropped)
|
||||
|
||||
# Log if we dropped anything
|
||||
if all_dropped_fields:
|
||||
logger.warning(f"Filtered unknown fields before insert: {all_dropped_fields}")
|
||||
|
||||
try:
|
||||
for filtered_json in filtered_data_list:
|
||||
|
|
@ -82,23 +76,22 @@ def _wrapped_insert(model_class: Type, data_list: dict | list, session: Session,
|
|||
session.add(instance)
|
||||
session.commit()
|
||||
|
||||
# the fix worked,
|
||||
logger.info("Finished wrapped insert!")
|
||||
return DatabaseOperation(
|
||||
valid=True,
|
||||
tried_filtered=True,
|
||||
message=f"Inserted after filtering {dropped_fields}"
|
||||
tried_filtered=bool(all_dropped_fields),
|
||||
message=f"Inserted successfully" + (f" after filtering {all_dropped_fields}" if all_dropped_fields else "")
|
||||
)
|
||||
|
||||
except Exception as retry_error:
|
||||
# Signal wrapper to rollback
|
||||
except Exception as e:
|
||||
# Unexpected error during insert
|
||||
session.rollback()
|
||||
raise WrapperRollback(DatabaseOperation(
|
||||
valid=False,
|
||||
error_type=DBErrorType.OLD_CLIENT_NEW_API,
|
||||
tried_filtered=True,
|
||||
message=str(f"Wrapped Insert Failed on Retry of a TypeError: {retry_error}")
|
||||
error_type=DBErrorType.UNEXPECTED_DB_ERROR,
|
||||
message=f"Wrapped Insert Failed: {str(e)}"
|
||||
))
|
||||
|
||||
|
||||
# =================== Isolation Test ======================
|
||||
"""
|
||||
Spoof Failure of an operational error to trigger/test a migration
|
||||
|
|
|
|||
Loading…
Reference in a new issue