mirror of
https://github.com/apache/superset.git
synced 2026-07-20 21:55:46 +00:00
fix(versioning): flag `description instead of uuid` in force-parent-dirty
flag_modified(parent, "uuid") was producing FK integrity failures via the column's BLOB/BINARY round-trip: SQLAlchemy logs the param as ``<memory at 0x…>`` and the UUID round-trip doesn't always match the in-memory value byte-for-byte. Symptom: in scenarios where the parent is already going to flush (Reverter applying historical state during restore, RLS test triggering autoflush during a query), our added ``uuid`` UPDATE column tripped the FK check. Pick ``description`` instead — plain Text column on all three versioned parent classes (Dashboard, Slice, SqlaTable), no TypeDecorator, no marshaling layer. Flagging it round-trips its current value safely. Fallback chain ``description → uuid → col_keys[0]`` keeps the original deterministic-pick property for forks/subclasses that excluded ``description``. Should unblock test_restore_applies_scalar_field and the test_rls_filter_alters_no_role_user_birth_names_query autoflush error.
This commit is contained in:
@@ -134,22 +134,34 @@ def _force_parent_dirty_on_child_change(session: Session) -> None:
|
||||
col_keys = [prop.key for prop in versioned_column_properties(parent)]
|
||||
if not col_keys:
|
||||
continue
|
||||
# ``uuid`` is on all three versioned parent classes (Dashboard,
|
||||
# Slice, SqlaTable) and is in none of their ``__versioned__``
|
||||
# excludes — pick it deterministically so the flagged attribute
|
||||
# is stable across SQLAlchemy versions / mapper-configuration
|
||||
# orders. Falls back to the first available column for forks or
|
||||
# subclasses that excluded ``uuid``.
|
||||
flag_col = "uuid" if "uuid" in col_keys else col_keys[0]
|
||||
# ``description`` is a plain ``Text`` column on all three versioned
|
||||
# parent classes (Dashboard, Slice, SqlaTable) and is in none of
|
||||
# their ``__versioned__`` excludes — pick it deterministically so
|
||||
# the flagged attribute is stable across SQLAlchemy versions /
|
||||
# mapper-configuration orders. We deliberately avoid ``uuid``
|
||||
# here: when a versioned-parent UPDATE goes through with ``uuid``
|
||||
# flagged, the column's ``UUIDType``/BLOB round-trip produces a
|
||||
# memoryview that fails an FK integrity check on some dialects
|
||||
# (observed in ``test_rls_filter_alters_no_role_user_birth_names_query``
|
||||
# and ``test_restore_applies_scalar_field``). ``description`` is
|
||||
# a plain text column with no marshaling layer, so flagging it
|
||||
# safely round-trips its current value. Falls back to ``uuid``
|
||||
# then ``col_keys[0]`` for forks that excluded ``description``.
|
||||
if "description" in col_keys:
|
||||
flag_col = "description"
|
||||
elif "uuid" in col_keys:
|
||||
flag_col = "uuid"
|
||||
else:
|
||||
flag_col = col_keys[0]
|
||||
try:
|
||||
attributes.flag_modified(parent, flag_col)
|
||||
except InvalidRequestError:
|
||||
# The parent is a freshly-constructed ``session.new`` instance
|
||||
# whose ``uuid`` default (``default=uuid4``) hasn't fired yet
|
||||
# — the attribute is unloaded in instance state, so
|
||||
# ``flag_modified`` rejects it. The parent will INSERT in this
|
||||
# flush regardless, so the flag was redundant; safely skip.
|
||||
# Hit by ``test_create_dataset_item`` (POST /api/v1/dataset/).
|
||||
# whose attribute defaults haven't fired yet — the attribute
|
||||
# is unloaded in instance state, so ``flag_modified`` rejects
|
||||
# it. The parent will INSERT in this flush regardless, so the
|
||||
# flag was redundant; safely skip. Hit by
|
||||
# ``test_create_dataset_item`` (POST /api/v1/dataset/).
|
||||
continue
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user