Skip to main content

Fixed: SADeprecationWarning "The noload loader strategy is deprecated" When You Run pytest with MLflow

· 7 min read
Jagdish Kumawat
Founder @ Dewiride

pytest passed all 12 tests of a project that logs to MLflow, then printed a warnings summary: SADeprecationWarning: The ``noload`` loader strategy is deprecated. It comes from MLflow 3.18.0's SQL tracking store meeting SQLAlchemy 2.1, and MLflow fixed it the day after 3.18.0 shipped. Until a release includes the fix, one filterwarnings line hides exactly this warning in your tests.

What I Was Doing​

I was running the tests of the house-price project from the MLflow series, with MLflow 3.18.0, pytest 9.2.0 and Python 3.15.2. The tests log real MLflow runs, to a temporary SQLite tracking database rather than to the tracking server:

Terminal
uv run pytest

What I Expected​

12 passed, with nothing else to read.

What I Got​

Output
============================================ test session starts =============================================
platform darwin -- Python 3.15.2, pytest-9.2.0, pluggy-1.7.0
rootdir: /Users/you/source/dewiride-house-price-prediction
configfile: pyproject.toml
plugins: anyio-4.16.0
collected 12 items

tests/test_config.py ... [ 25%]
tests/test_data.py ... [ 50%]
tests/test_plots.py . [ 58%]
tests/test_train.py ..... [100%]

============================================== warnings summary ==============================================
tests/test_train.py::test_a_run_logs_params_metrics_tags_and_the_chart
/Users/you/source/dewiride-house-price-prediction/.venv/lib/python3.15/site-packages/mlflow/store/tracking/sqlalchemy_store.py:356: SADeprecationWarning: The ``noload`` loader strategy is deprecated and will be removed in a future release. This option produces incorrect results by returning ``None`` for related items. (deprecated since: 2.1)
sqlalchemy.orm.configure_mappers()

-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
======================================= 12 passed, 1 warning in 3.16s ========================================

A terminal running uv run pytest: 12 tests pass, then a warnings summary shows SADeprecationWarning: The noload loader strategy is deprecated, raised in mlflow/store/tracking/sqlalchemy_store.py line 356, and the last line reads 12 passed, 1 warning.

All tests passed. pytest listed the warning under the one test that logs a full run.

What I Checked​

Whose code it points at. mlflow/store/tracking/sqlalchemy_store.py, line 356, is MLflow's SQL tracking store, the code that reads and writes mlflow.db. The line itself, sqlalchemy.orm.configure_mappers(), asks SQLAlchemy, the database library MLflow uses, to check every table model MLflow defines.

Which model uses noload. One relationship in MLflow 3.18.0's table models, mlflow/store/tracking/dbmodels/models.py, line 4715, still asks for it:

mlflow/store/tracking/dbmodels/models.py (MLflow 3.18.0)
# Never auto-loaded (noload) — only filled by explicit JOIN.
resolved_version_rel = relationship(
"SqlMCPServerVersion",
...
viewonly=True,
lazy="noload",
)

It belongs to SqlMCPAccessEndpoint, part of a GenAI feature, but SQLAlchemy checks every model, so any use of the SQL store meets it.

The SQLAlchemy version. MLflow installed SQLAlchemy 2.1.8 as a dependency, and the warning ends with (deprecated since: 2.1).

MLflow's issue tracker. The problem is mlflow/mlflow#27466, "[BUG] SADeprecationWarning for lazy="noload" with SQLAlchemy 2.1 on any SQL-backed store". Its fix, mlflow/mlflow#27467, "Replace deprecated lazy="noload" with lazy="raise" on SqlMCPAccessEndpoint.resolved_version_rel", was merged on November 5, 2026 at 05:46 UTC. MLflow 3.18.0 had been released the day before, on November 4 at 06:51 UTC, so it doesn't contain the fix. When I checked on November 13, 2026, 3.18.0 was still the newest release.

Why only pytest showed it. SADeprecationWarning is a kind of DeprecationWarning, which Python hides by default outside your own script. pytest's documentation: "By default pytest will display DeprecationWarning and PendingDeprecationWarning warnings from user code and third-party libraries, as recommended by PEP 565." The same project's training runs never printed it.

Why It Happens​

SQLAlchemy 2.1 deprecated the noload loading strategy and warns whenever a model uses it. MLflow 3.18.0 still had one model with lazy="noload", and its SQL tracking store makes SQLAlchemy check all models the first time it's used. Tests that log to a SQLite file use that store, and pytest shows deprecation warnings that a normal run hides.

The Fix​

The real fix is the next MLflow release that includes #27467. Until then, tell pytest to ignore this one warning. In pyproject.toml, add pytest settings with a filterwarnings list:

pyproject.toml (pytest settings)
[tool.pytest]
testpaths = ["tests"]
filterwarnings = [
# MLflow 3.18.0 still uses lazy="noload", which SQLAlchemy 2.1 deprecates. The fix
# (mlflow/mlflow#27467) ships after 3.18.0: delete this line once you upgrade MLflow.
'ignore:The ``noload`` loader strategy is deprecated:sqlalchemy.exc.SADeprecationWarning',
]

The pytest settings of pyproject.toml in a macOS-style code window: the tool.pytest table with testpaths set to tests and a filterwarnings list holding one ignore filter for the noload deprecation message and the sqlalchemy.exc.SADeprecationWarning category, under a comment saying to delete it after upgrading MLflow.

  • [tool.pytest] is pytest 9's own table in pyproject.toml. Its documentation: "Use [tool.pytest] to leverage native TOML types (supported since pytest 9.0)". On older pytest, the table is [tool.pytest.ini_options].
  • The filter reads action:message:category: ignore this warning, when its message starts with The ``noload`` loader strategy is deprecated and its type is sqlalchemy.exc.SADeprecationWarning. pytest treats the message as "a regular expression that the start of the warning message must match".
  • Single quotes make it a TOML literal string, so nothing inside is treated as an escape. pytest's own example uses them for the same reason.
  • The comment says when to delete the line, so it doesn't outlive the problem.

After the Fix​

Terminal
uv run pytest
Output
============================================ test session starts =============================================
platform darwin -- Python 3.15.2, pytest-9.2.0, pluggy-1.7.0
rootdir: /Users/you/source/dewiride-house-price-prediction
configfile: pyproject.toml
testpaths: tests
plugins: anyio-4.16.0
collected 12 items

tests/test_config.py ... [ 25%]
tests/test_data.py ... [ 50%]
tests/test_plots.py . [ 58%]
tests/test_train.py ..... [100%]

============================================= 12 passed in 2.93s =============================================

12 passed, no warnings summary. The new testpaths: tests line shows pytest reading the settings.

Common Mistakes​

MistakeWhat happensDo this instead
Ignoring every DeprecationWarningWarnings about your own code disappear tooFilter by message and category
Leaving the filter in after upgrading MLflowIt may hide the warning if it ever comes backDelete it when a release includes the fix

Troubleshooting​

SymptomLikely causeFix
The warning still showsThe settings are in a table pytest doesn't readUse [tool.pytest] on pytest 9, [tool.pytest.ini_options] before it
testpaths: tests doesn't appear in the headerpytest isn't reading pyproject.toml's settingsRun pytest from the folder that holds pyproject.toml

FAQ​

Do my tests or runs give wrong results?​

Not for experiment tracking. All 12 tests passed, and the warning is about one relationship of a GenAI model that tracking runs don't use; MLflow's own comment on it says it's never loaded automatically.

Will upgrading SQLAlchemy or MLflow remove it?​

Upgrading MLflow to a release that includes #27467 will. Check MLflow's release notes for it, then delete the filter.

Does the tracking server print it?​

Not in its startup log: the server runs outside pytest, where Python hides deprecation warnings by default.

Conclusion​

SADeprecationWarning: The ``noload`` loader strategy is deprecated comes from one lazy="noload" relationship in MLflow 3.18.0, reported by SQLAlchemy 2.1.8 and shown by pytest. MLflow fixed it after 3.18.0 was released. A single filterwarnings entry under [tool.pytest] hides exactly that warning until the next release.

Additional Resources​