Abdulrehman-PIAIC80387 opened a new pull request, #41994:
URL: https://github.com/apache/superset/pull/41994
### SUMMARY
Fixes #38629.
Deleting a user via Settings → Security → List Users → Delete raises
`IntegrityError` on PostgreSQL, MySQL, and MariaDB when the user has any
dependent rows in tables that reference `ab_user.id` via foreign keys without
`ON DELETE` behavior — e.g. `logs`, `key_value`, `favstar`, `saved_query`,
`user_attribute`, or any table using `AuditMixinNullable` (dashboards, slices,
dbs, tables, ...).
The fix:
- adds `ondelete="SET NULL"` to `AuditMixinNullable.created_by_fk` and
`changed_by_fk` at the model layer (covers ~29 tables through the shared mixin)
- adds `ondelete=` to ~10 direct `ForeignKey("ab_user.id")` declarations in
models (`logs`, `favstar`, `saved_query`, `query`, `key_value`,
`slices.last_saved_by_fk`, `tab_state`, `user_attribute`, `user_favorite_tag`)
- adds an Alembic migration that DROPs and RECREATEs the affected FK
constraints (~60 total) with the correct `ON DELETE` clause, using a local
helper that filters by `local_cols` (the shared `redefine()` helper matches
only by referred columns and would collide on tables with multiple FKs to
`ab_user.id`)
- adds a regression test
(`tests/unit_tests/models/test_user_delete_cascade.py`, 12 tests) that
introspects `Model.metadata` and pins that every FK to `ab_user.id` declares
`ondelete` — so a future contributor cannot silently reintroduce the bug
**Semantic rules:**
- Audit-trail columns (`created_by_fk`, `changed_by_fk`, `logs.user_id`,
`saved_query.user_id`, `query.user_id`, `key_value.*`,
`slices.last_saved_by_fk`) → `SET NULL`. The row survives when its author is
deleted; the audit reference is cleared.
- Ownership columns (`favstar.user_id`, `user_attribute.user_id`,
`tab_state.user_id`, `user_favorite_tag.user_id`) → `CASCADE`. The row has no
meaning without the user.
Same pattern as the 2023 owners-references migration (`6d05b0a70c89`) and
the 2025 FAB tables migration (`32bf93dfe2a4`).
### TESTING INSTRUCTIONS
**Manual repro on Postgres:**
```sql
-- Before fix: this fails with IntegrityError
INSERT INTO ab_user (id, first_name, last_name, username, email, active,
created_on, changed_on)
VALUES (999, 'Test', 'DeleteMe', 'test_delete_me', '[email protected]', true,
NOW(), NOW());
INSERT INTO logs (id, action, user_id, dttm) VALUES (999901, 'test', 999,
NOW());
INSERT INTO key_value (id, resource, value, created_by_fk) VALUES (999901,
'test', decode('deadbeef', 'hex'), 999);
INSERT INTO favstar (id, user_id, class_name, obj_id, dttm) VALUES (999901,
999, 'Dashboard', 1, NOW());
DELETE FROM ab_user WHERE id = 999; -- Before: IntegrityError. After:
DELETE 1
```
After the fix (verified locally on PG):
- `logs.user_id` → NULL (row survives)
- `key_value.created_by_fk` → NULL (row survives)
- `favstar` row is cascade-deleted
**Also reproducible via UI:** log in as admin, create a second user, log in
as them and favorite a dashboard + save a SQL Lab query, log out, delete them
via Settings → List Users. Before: "There was an issue deleting record" toast.
After: user is deleted cleanly.
**Automated:**
```bash
pytest tests/unit_tests/models/test_user_delete_cascade.py -v
```
### ADDITIONAL INFORMATION
- [x] Has associated issue: Fixes #38629
- [x] Required feature flags: none
- [x] Changes UI: no
- [x] Includes DB Migration: **yes** — one Alembic migration adds ON DELETE
clauses to ~60 FK constraints, idempotent-safe (helper skips missing
tables/columns and matches existing constraints by `local_cols`)
- [x] Includes CLI or Node.js commands: no
- [x] Breaking change: no
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]