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__}")
|
logger.info(f"Starting insert for {model_class.__name__}")
|
||||||
|
|
||||||
try:
|
# Get valid field names upfront
|
||||||
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()
|
|
||||||
|
|
||||||
valid_fields = {col.name for col in model_class.__table__.columns}
|
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))
|
# Filter data proactively
|
||||||
if dropped_fields:
|
filtered_data_list = []
|
||||||
logger.warning(f"Old Client Dropped unknown fields: {dropped_fields}")
|
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:
|
try:
|
||||||
for filtered_json in filtered_data_list:
|
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.add(instance)
|
||||||
session.commit()
|
session.commit()
|
||||||
|
|
||||||
# the fix worked,
|
logger.info("Finished wrapped insert!")
|
||||||
return DatabaseOperation(
|
return DatabaseOperation(
|
||||||
valid=True,
|
valid=True,
|
||||||
tried_filtered=True,
|
tried_filtered=bool(all_dropped_fields),
|
||||||
message=f"Inserted after filtering {dropped_fields}"
|
message=f"Inserted successfully" + (f" after filtering {all_dropped_fields}" if all_dropped_fields else "")
|
||||||
)
|
)
|
||||||
|
|
||||||
except Exception as retry_error:
|
except Exception as e:
|
||||||
# Signal wrapper to rollback
|
# Unexpected error during insert
|
||||||
|
session.rollback()
|
||||||
raise WrapperRollback(DatabaseOperation(
|
raise WrapperRollback(DatabaseOperation(
|
||||||
valid=False,
|
valid=False,
|
||||||
error_type=DBErrorType.OLD_CLIENT_NEW_API,
|
error_type=DBErrorType.UNEXPECTED_DB_ERROR,
|
||||||
tried_filtered=True,
|
message=f"Wrapped Insert Failed: {str(e)}"
|
||||||
message=str(f"Wrapped Insert Failed on Retry of a TypeError: {retry_error}")
|
|
||||||
))
|
))
|
||||||
|
|
||||||
|
|
||||||
# =================== Isolation Test ======================
|
# =================== Isolation Test ======================
|
||||||
"""
|
"""
|
||||||
Spoof Failure of an operational error to trigger/test a migration
|
Spoof Failure of an operational error to trigger/test a migration
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue