@tiangolo can you provide some information if / how it possible to leverage SQLalchemy's deferred loading mechanism in SQLModel ?
I also could not find a way to make deferred loading on column level (not on query level) work. sa_column setting is not recognized by SQLModel and still loads the deferred column
It seems that for now there is no way to declare model with the deferred field, and we can only defer column loading by specifying the option for query:
Came looking for support, found this issue, determined a workaround...
fromtypingimportListimportsqlalchemyimportsqlalchemy.ormimportsqlmodeldefdefer_columns(*columns: List[str]):
defdefer_columns_for_sqlmodel_class(cls):
mapper=sqlalchemy.inspect(cls)
forcolumnincolumns:
prop=mapper.get_property(column)
prop.deferred=Truenew_strategy= []
# we expect strategy_key to be a tuple of (name, value) pairs but we're# going to be extra careful here...forstrategyinprop.strategy_key:
if (
isinstance(strategy, tuple)
andlen(strategy) ==2andisinstance(strategy[0], str)
andstrategy[0] =="deferred"
):
new_strategy.append(("deferred", True))
else:
new_strategy.append(strategy)
prop.strategy_key=tuple(new_strategy)
# normally invoked automatically, but you might need to do this explicitly if# you're up to really unusual things...# sqlalchemy.orm.configure_mappers()returnclsreturndefer_columns_for_sqlmodel_class@defer_columns("deferred_by_default")classFoo(sqlmodel.SQLModel, table=True):
id: int=sqlmodel.Field(primary_key=True)
always_loaded: strdeferred_by_default: strdefget_attrs(model):
"Return underling attributes."returnmodel._sa_instance_state.dict# test_engine is a pytest fixture with a working test DB connection. YMMVdeftest_deferred(test_engine):
session=sqlmodel.Session(test_engine)
session.add(Foo(id=1, always_loaded="Happy", deferred_by_default="Sad"))
session.commit()
session.expire_all()
select=sqlmodel.select(Foo).where(Foo.id==1)
explicitly_deferred=session.exec(
select.options(sqlalchemy.orm.defer(Foo.deferred_by_default))
).one()
assert"always_loaded"inget_attrs(explicitly_deferred)
assert"deferred_by_default"notinget_attrs(explicitly_deferred)
session.expire_all()
explicitly_loaded=session.exec(
select.options(sqlalchemy.orm.undefer(Foo.deferred_by_default))
).one()
assert"deferred_by_default"inget_attrs(explicitly_loaded)
session.expire_all()
foo=session.exec(select).one()
assert"deferred_by_default"notinget_attrs(foo)
Reacted by Alessia Marcolini, Hank, Will Blaschko and UncleDrew92
Activity
eddcorts commented on Mar 25, 2022
Having same issue, did you find any alternative with base SQLAlchemy or something?
FilipeMarch commented on May 13, 2023
Did you find a solution?
lucas-labs commented on Nov 9, 2023
I think that we can use the new sa_type now, in order to achieve this behaviour.
ngi commented on Mar 28, 2024
any news how to use sa_type for deferred loading?
MarkusDressel commented on Nov 14, 2024
@tiangolo can you provide some information if / how it possible to leverage SQLalchemy's deferred loading mechanism in SQLModel ?
I also could not find a way to make deferred loading on column level (not on query level) work. sa_column setting is not recognized by SQLModel and still loads the deferred column
Fatem-Mq commented on Feb 28, 2025
Any updates? =(
shawnmartin-py commented on Feb 28, 2025
Why anyone would even consider sqlmodel these days is beyond me.
Been fine managing Pydantic and SQLA models independently for the past 3 years.
shawnmartin-py commented on Feb 28, 2025
It's a lib that get's hardly any updates, and only 1 person is allowed to merge PR's. 🤦♂️
alessiamarcolini commented on Jul 25, 2025
Hi! Is there an update on how to make this work? :) Thanks.
YuriiMotov commented on Aug 13, 2025
It seems that for now there is no way to declare model with the deferred field, and we can only defer column loading by specifying the option for query:
or
justanotherbody commented on Jan 16, 2026
Came looking for support, found this issue, determined a workaround...
natikos commented on Feb 13, 2026
any updates on this issue?