Skip to content

Render JSONB partial updates inside PydanticColumn via JsonbMerge #14470

Description

@HyeockJinKim

TriState / OptionalState decide whether a column is written. Inside a JSONB column storing a Pydantic model there is no counterpart, so an updater rebuilds the whole document from whatever the request carried and the keys the request omitted fall back to their defaults.

Confirmed live cases: resource_slot_types.number_format sending only binary resets round_length; scaling_groups.scheduler_opts.preemption sending one field resets the other five; prometheus_query_presets.options needs one hand-written jsonb_set branch per combination of fields.

Change

  • PydanticColumn learns the column it is attached to (TypeDecorator is a SchemaEventTarget) and renders a partial update itself in bind_expression.
  • A bound JsonbMerge is written as a recursive merge onto the stored document, so sibling keys the patch does not mention survive. Any other value replaces the document whole, unchanged from today.
  • PydanticListColumn refuses a JsonbMerge: on an array the concatenation operator appends instead of merging, which would corrupt the document without raising.
  • First application: the prometheus query preset updater drops its per-combination jsonb_set branching.

Scope

No API or schema change. Exposing partial updates on the preemption and number_format request DTOs widens GraphQL input types and is filed separately.

Verification

A test collects every declared PydanticColumn and PydanticListColumn from the mapped metadata and runs the same scenarios against each, so a column added later is covered without editing the test.

Known limit: a JsonbMerge bound into an INSERT references the target column in VALUES and PostgreSQL rejects it. The hook cannot see the statement kind; the behaviour is asserted so it is a known one.

JIRA Issue: BA-7795

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions