Add CASCADE to logged_model tables experiment_id foreign keys#20185
Add CASCADE to logged_model tables experiment_id foreign keys#20185harupy merged 13 commits intomlflow:masterfrom
logged_model tables experiment_id foreign keys#20185Conversation
🛠 DevTools 🛠
Install mlflow from this PRFor Databricks, use the following command: |
logged_model tables experiment_id foreign keys
There was a problem hiding this comment.
Pull request overview
This pull request adds ON DELETE CASCADE to the experiment_id foreign key constraints in the logged_model_params, logged_model_tags, and logged_model_metrics tables. This change fixes a foreign key constraint error that occurs when mlflow gc attempts to delete experiments that have associated logged model records.
Changes:
- Updated SQLAlchemy model definitions to include
ondelete="CASCADE"for experiment_id foreign keys - Created database migration to alter existing constraints
- Updated schema file to reflect the new constraint definitions
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| mlflow/store/tracking/dbmodels/models.py | Added ondelete="CASCADE" parameter to experiment_id foreign key constraints in SqlLoggedModelMetric, SqlLoggedModelParam, and SqlLoggedModelTag classes |
| mlflow/store/db_migrations/versions/92d5b24e0351_add_cascade_to_logged_model_experiment_fks.py | Created migration to drop and recreate foreign key constraints with CASCADE deletion for the three logged_model tables |
| tests/resources/db/latest_schema.sql | Updated schema definition to include ON DELETE CASCADE in the SQL foreign key constraint definitions |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
Documentation preview for 2740ccc is available at: More info
|
VerificationI verified the fix by running the new test against MySQL using Docker: Without the fix (migration removed):With the fix:Commands used:# Build the MySQL service
./tests/db/compose.sh build --build-arg DEPENDENCIES="$(uv run python dev/extract_deps.py)" mlflow-mysql
# Run the test against MySQL
./tests/db/compose.sh run --rm mlflow-mysql pytest tests/db/test_tracking_operations.py::test_gc_experiment_with_logged_model_params_and_tags -vThe test is also added to |
|
/autoformat |
tests/db/test_tracking_operations.py
Outdated
| assert exp_id not in [e.experiment_id for e in experiments] | ||
|
|
||
| with pytest.raises(mlflow.MlflowException, match=r".+ not found"): | ||
| client.get_logged_model(model.model_id) |
There was a problem hiding this comment.
the test doesn't seems sufficient,
we need to query the 3 tables SqlLoggedModelTag, SqlLoggedModelParam, SqlLoggedModelMetric to assert related records are deleted.
|
Hey @harupy and @WeichenXu123, Thanks for working on this fix, @harupy! We've independently run into the same issue and arrived at a similar solution, which is how we discovered this PR. It looks like only the test adjustments are outstanding. We'd be happy to help get this across the finish line if that would be useful. @harupy, if you have time to address the remaining comments, we'd be glad to let you complete it. However, if you're busy or would prefer us to take it from here, we're also more than willing to take over and push it through. Either way works for us! @WeichenXu123, from a maintainer perspective, does this approach look good to you? Would you be open to merging once the tests are adjusted? We think this fix would benefit quite a few users experiencing the same issue, so we're keen to help however we can. |
|
Hi @harupy, I’ve encountered the same foreign key constraint issue during GC and am very interested in seeing this fix merged. I noticed there are currently some failing CI checks. I’d be happy to help move this forward—would you like me to look into the test failures or perhaps provide some additional manual testing on my environment to verify the fix? Thanks for working on this! |
Fix for GitHub issue mlflow#20184: GC fails when deleting experiments if there are records in logged_model_params, logged_model_tags, or logged_model_metrics tables that reference the experiment. The experiment_id FK constraints in these tables were missing ON DELETE CASCADE, causing the database to reject experiment deletion. This follows the same pattern used for the logged_models.experiment_id FK which correctly has CASCADE. Co-Authored-By: Claude <noreply@anthropic.com> Signed-off-by: harupy <17039389+harupy@users.noreply.github.com>
Adds a regression test for mlflow#20184 Co-Authored-By: Claude <noreply@anthropic.com> Signed-off-by: harupy <17039389+harupy@users.noreply.github.com>
Adds a test that reproduces the FK constraint error from issue mlflow#20184 when run against MySQL with enforced foreign key constraints. Co-Authored-By: Claude <noreply@anthropic.com> Signed-off-by: harupy <17039389+harupy@users.noreply.github.com>
52a0cb1 to
c61d5d8
Compare
Replace DB-level ondelete="CASCADE" on experiment_id FKs (which breaks MSSQL due to multiple cascade paths) with an ORM relationship from SqlLoggedModel to SqlExperiment. This lets session.delete(experiment) cascade through ORM: experiment → logged_models → params/tags/metrics. Co-Authored-By: Claude <noreply@anthropic.com> Signed-off-by: harupy <17039389+harupy@users.noreply.github.com>
- Update latest_schema.sql to remove ON DELETE CASCADE from experiment_id FKs on logged_model_params/tags/metrics (matching models.py) - Use CliRunner instead of subprocess in SQLite test - Pass --backend-store-uri explicitly in DB test - Assert child table records (params, tags) are deleted after GC Co-Authored-By: Claude <noreply@anthropic.com> Signed-off-by: harupy <17039389+harupy@users.noreply.github.com>
Signed-off-by: harupy <17039389+harupy@users.noreply.github.com>
Address review feedback to assert all 3 child tables (params, tags, metrics) are cleaned up after GC deletes an experiment with logged models. Co-Authored-By: Claude <noreply@anthropic.com> Signed-off-by: harupy <17039389+harupy@users.noreply.github.com>
|
Both tests now assert all 3 tables ( |
Co-Authored-By: Claude <noreply@anthropic.com> Signed-off-by: harupy <17039389+harupy@users.noreply.github.com>
The DB test (tests/db/test_tracking_operations.py) already covers this against MySQL/PostgreSQL where FK constraints are strictly enforced. Co-Authored-By: Claude <noreply@anthropic.com> Signed-off-by: harupy <17039389+harupy@users.noreply.github.com>
Co-Authored-By: Claude <noreply@anthropic.com> Signed-off-by: harupy <17039389+harupy@users.noreply.github.com>
Co-Authored-By: Claude <noreply@anthropic.com> Signed-off-by: harupy <17039389+harupy@users.noreply.github.com>
The ORM cascade fix is DB-engine agnostic, so a SQLite test is sufficient. Co-Authored-By: Claude <noreply@anthropic.com> Signed-off-by: harupy <17039389+harupy@users.noreply.github.com>
Co-Authored-By: Claude <noreply@anthropic.com> Signed-off-by: harupy <17039389+harupy@users.noreply.github.com>
…flow#20185) Signed-off-by: harupy <17039389+harupy@users.noreply.github.com> Co-authored-by: Claude <noreply@anthropic.com>
…flow#20185) Signed-off-by: harupy <17039389+harupy@users.noreply.github.com> Co-authored-by: Claude <noreply@anthropic.com>
…0185) Signed-off-by: harupy <17039389+harupy@users.noreply.github.com> Co-authored-by: Claude <noreply@anthropic.com>
Related Issues/PRs
Resolve #20184
What changes are proposed in this pull request?
Add
ON DELETE CASCADEto theexperiment_idforeign key constraints inlogged_model_params,logged_model_tags, andlogged_model_metricstables. This fixes GC failing when attempting to delete experiments that have associated logged model records.How is this PR tested?
Does this PR require documentation update?
Release Notes
Is this a user-facing change?
Fix
mlflow gcfailing with foreign key constraint error when deleting experiments with logged model records.What component(s), interfaces, languages, and integrations does this PR affect?
Components
area/tracking: Tracking Service, tracking client APIs, autologgingHow should the PR be classified in the release notes? Choose one:
rn/bug-fix- A user-facing bug fix worth mentioning in the release notesShould this PR be included in the next patch release?
🤖 Generated with Claude Code