fix: snapshot nullable columns correctly in WatchedFieldsMixin callback (#194)

This commit is contained in:
d3vyce
2026-03-28 18:47:06 +01:00
committed by GitHub
parent f4698bea8a
commit f5afbbe37f
2 changed files with 101 additions and 8 deletions

View File

@@ -27,6 +27,7 @@ _SESSION_CREATES = "_ft_creates"
_SESSION_DELETES = "_ft_deletes"
_SESSION_UPDATES = "_ft_updates"
_SESSION_SAVEPOINT_DEPTH = "_ft_sp_depth"
_DEFERRED_STRATEGY_KEY = (("deferred", True), ("instrument", True))
class ModelEvent(str, Enum):
@@ -60,11 +61,22 @@ def _snapshot_column_attrs(obj: Any) -> dict[str, Any]:
"""Read currently-loaded column values into a plain dict."""
state = sa_inspect(obj) # InstanceState
state_dict = state.dict
return {
prop.key: state_dict[prop.key]
for prop in state.mapper.column_attrs
if prop.key in state_dict
}
snapshot: dict[str, Any] = {}
for prop in state.mapper.column_attrs:
if prop.key in state_dict:
snapshot[prop.key] = state_dict[prop.key]
elif (
not state.expired
and prop.strategy_key != _DEFERRED_STRATEGY_KEY
and all(
col.nullable
and col.server_default is None
and col.server_onupdate is None
for col in prop.columns
)
):
snapshot[prop.key] = None
return snapshot
def _get_watched_fields(cls: type) -> list[str] | None: