You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
this option was added as kind of a one-off about 18 years ago to suit an example case for custom loading of relationships which I'd never recommend today. because the option turns off the related attribute entirely, it has all kinds of not easily predictable behaviors, it returns essentially incorrect results (e.g. None when there would normally be a collection there) and we continue to get complaints about other features not working when it's used e.g. #11040.
The one place people use this is when they have some kind of serializer that touches every attribute and they dont want an attribute to load. I think that's a bad use case. They should do one of 1. dont have that relationship there if it isnt part of the object's state 2. get a serializer that can select for which attributes you want to serialize and which you dont 3. eagerly load the collection there. it's no different from an object with a relationship that has a huge list of related objects already loaded and you don't want to serialize that either.
so let's just deprecate it and we dont have to deal with complaints anymore, people will write better programs.
Can we work around this by using raiseload with try-except clauses?
# previously noload('*'); (pseudo-code not tested)user=session.execute(select(User).options(raiseload('*'))).scalar_one()
try:
contacts=user.contactsexceptInvalidRequestError:
contacts=None
So that we can access user.contacts if it's eagerly loaded and get None if it's not explicitly eagerly loaded?
They should [...] 2. get a serializer that can select for which attributes you want to serialize and which you dont
In a project I work on, noload('*') + selectinload(...)' is the means to select which attributes get serialized: Different queries of Userwill specifynoload('*')with differentselectinload(User.contacts)orselectinload(User.biography), etc. And the result is converted to a domain model by a common map_user_to_domain_model(user), which tries to convert all relations that are not None` to dataclasses.
Maybe not the best use case and this deprecation could be a reason to move away from this model. But I'd appreciate to have a workaround as this would require us to completely redesign our domain models (and all the functions using them, how the data is passed around, etc.). In our case much more effort than the 1.4 -> 2.0 migration.
people will write better programs
🙏 (the type checker would also be happy about this change :)
Activity
sqla-tester commentedon Jan 24, 2025
Federico Caselli has proposed a fix for this issue in the main branch:
The
noloadloader option is now deprecated. https://gerrit.sqlalchemy.org/c/sqlalchemy/sqlalchemy/+/5670Otto-AA commentedon Mar 23, 2026
Can we work around this by using
raiseloadwith try-except clauses?So that we can access
user.contactsif it's eagerly loaded and getNoneif it's not explicitly eagerly loaded?In a project I work on,
noload('*') + selectinload(...)' is the means to select which attributes get serialized: Different queries ofUserwill specifynoload('*')with differentselectinload(User.contacts)orselectinload(User.biography), etc. And the result is converted to a domain model by a commonmap_user_to_domain_model(user), which tries to convert all relations that are notNone` to dataclasses.Maybe not the best use case and this deprecation could be a reason to move away from this model. But I'd appreciate to have a workaround as this would require us to completely redesign our domain models (and all the functions using them, how the data is passed around, etc.). In our case much more effort than the 1.4 -> 2.0 migration.
🙏 (the type checker would also be happy about this change :)
CaselIT commentedon Mar 23, 2026
That should work, but if you prefer LBYL instead of EAFP you can use https://docs.sqlalchemy.org/en/20/orm/internals.html#sqlalchemy.orm.InstanceState.unloaded to check if a relationship is loaded or not.
Something like
SQLA: Replace the deprecated `lazy="noload"` with `lazy="raise"`
SQLA: Replace the deprecated `lazy="noload"` with `lazy="raise"`
SQLA: Replace the deprecated `lazy="noload"` with `lazy="raise"`
SQLA: Replace the deprecated `lazy="noload"` with `lazy="raise"`
SQLA: Replace the deprecated `lazy="noload"` with `lazy="raise"`
SQLA: Replace the deprecated `lazy="noload"` with `lazy="raise"` (#64262
SQLA: Replace the deprecated `lazy="noload"` with `lazy="raise"` (apa…
SQLA: Replace the deprecated `lazy="noload"` with `lazy="raise"` (apa…
SQLA: Replace the deprecated `lazy="noload"` with `lazy="raise"` (#64…
Replace deprecated sqlalchemy.orm.noload
Update git submodules
Replace deprecated SQLAlchemy noload and return get_all_orm for L7 po…
Update git submodules