Skip to content

fix(generators): deleting an entity deletes its association-class links - #598

Merged
ArmenSl merged 1 commit into
developmentfrom
fix/assoc-class-cascade-delete
Sep 9, 2026
Merged

fix(generators): deleting an entity deletes its association-class links#598
ArmenSl merged 1 commit into
developmentfrom
fix/assoc-class-cascade-delete

Conversation

@ArmenSl

@ArmenSl ArmenSl commented Sep 9, 2026

Copy link
Copy Markdown
Collaborator

What

Deleting an entity that has association-class links (e.g. a Booking with ReservedRoom rows) crashed the generated backend, and the generated table could not delete a link row at all.

  • sql_alchemy: entity → links relationships of every association class now carry cascade="all, delete-orphan" (both ends). Their FK is part of the link's composite PK, so without the cascade SQLAlchemy raised "Dependency rule tried to blank-out primary key column" on delete.
  • backend routers: DELETE returns a column snapshot of the deleted row instead of the live ORM object — the cascade loads back-references that made the JSON encoder recurse endlessly.
  • react: the table binding now names its row_key_fields (declared is_id attribute, or both FKs in the backend's route order for an association class) and getRowId builds the path from them. Previously it guessed the first column of the row, which for a ReservedRoom was the price → DELETE /reservedroom/88.0/.

Tests

End-to-end cascade from both ends + link deletion (backend, ASGI-driven), row_key_fields serialization (react), cascade emission (sqlalchemy). Verified live against the hotel-booking model: create booking with two rooms → delete a link → delete the booking → no orphan rows.

Deleting a Booking that had ReservedRoom links crashed the generated
backend with SQLAlchemy's "Dependency rule tried to blank-out primary key
column" AssertionError: the link's FK is part of its composite primary
key, so the ORM could neither null it nor knew to delete the row. And the
generated table could not delete a link row at all, because it guessed the
row id from the first column (the price) and called /reservedroom/88.0/.

- sql_alchemy: the entity -> links relationship of every association class
  carries cascade="all, delete-orphan" (both ends), so deleting an entity
  deletes its link rows; the link -> entity side stays cascade-free.
- backend routers: DELETE returns a snapshot of the deleted row's columns
  instead of the live ORM object, whose cascade-loaded back-references
  made the JSON encoder recurse endlessly.
- react: the table binding names its row key fields (declared is_id
  attribute, or both foreign keys in the backend's route order for an
  association class) and getRowId builds the path from them, so
  DELETE/PUT of a Room hits /room/{number}/ and of a link
  /reservedroom/{booking_id}/{rooms_id}/.

Tests: end-to-end cascade from both ends and link deletion (backend),
row_key_fields serialization (react), cascade emission (sqlalchemy).
Verified live on the hotel-booking model.
@ArmenSl
ArmenSl merged commit 393493c into development Sep 9, 2026
5 checks passed
@ArmenSl
ArmenSl deleted the fix/assoc-class-cascade-delete branch September 9, 2026 11:41
ArmenSl added a commit that referenced this pull request Sep 9, 2026
…tiplicity enforcement in generated apps

- Bump setup.cfg 7.14.1 -> 7.14.2 and add the v7.14.2 release notes.
- Backend: modular per-file FastAPI generator (#597), association-class
  cascade delete and real row keys (#598), lower-bound multiplicity guards,
  omitted-list PUT, inherited-attribute PUT, and the generated dialog fixes
  (detailed prefill, request loop, delete-error banner).
- Frontend submodule unchanged: develop and main are already in sync.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant