mirror of
https://github.com/apache/superset.git
synced 2026-09-07 15:54:55 +00:00
Root cause of the ReportSchedule "is not persisted" InvalidRequestError and the cascaded StaleDataError/PendingRollbackError fan-out seen across charts/api_tests.py and dashboards/api_tests.py in CI: SQLAlchemy 2.0 removes the legacy cascade_backrefs behavior entirely. Under 1.4, constructing `ReportSchedule(chart=chart)` where `chart` was already a persistent, session-tracked object implicitly added the new ReportSchedule to the session too, via the Slice.report_schedules backref collection. That auto-cascade is gone in 2.0 (this is a documented, intentional SQLAlchemy 1.4->2.0 removal, not a bug) - an explicit db.session.add() is now required. Without it, `create_chart_with_report`/`create_dashboard_with_report` committed a ReportSchedule that was silently never persisted. The actual test bodies then found no report attached (delete succeeded with 200 instead of the expected 422 block), and fixture teardown's `db.session.delete(report_schedule)` blew up with "Instance ... is not persisted" since the object was transient all along. The dashboard variant's cascading StaleDataError on dashboard_slices was a downstream symptom of the same root cause (the "blocked" dashboard delete actually went through). Other ReportSchedule(...) construction sites in the test suite already call db.session.add() explicitly (deletion_retention/*, charts/ soft_delete_tests.py, databases/api_tests.py, reports/utils.py) or never persist the object at all (reports/alert_tests.py, reports/commands_tests.py) - these two fixtures were the only ones missing it. Production code is unaffected: BaseDAO.create() already calls db.session.add() explicitly, so the real create-report code path never relied on the removed cascade. Verified locally (real flask-sqlalchemy==3.1.1 + sqlalchemy==2.0.51, sqlite backend): tests/integration_tests/charts/api_tests.py (96/96) and tests/integration_tests/dashboards/api_tests.py (156/156) both pass clean after this fix, including the two previously-failing report-block tests and the dashboard_slices StaleDataError case.