Dependency Injection via SQLModels isn't worth it
Dependency Injection via SQLModels isn’t worth it
February 2025
It’s been something I’ve been mulling over for a while now. I’m not convinced
using Session with
Dependency Injection is worth it.
The abstraction is nice, visually, but the lack of context makes things really
hard to reason with, especially if you’re doing something beyond a simple
getter/setter. This happens if you’re building an application that performs a
flow or some business logic rather than a pure CRUD, then you may need to do
multiple commits in a single query which may not need to all be rolled back.
This of course breaks some kind of assumption to do with “a single unit of
work”.
I encountered this in one of the more painful ways, and instead reverted back to
how the sqlalchemy orm does it. With that in mind, I thought this is a quick
note to remind myself to beware, think and plan things out better, because I
undoubtedly will try something stupid like this again.
Using sqlalchemy:
1from contextlib import contextmanager
2
3from sqlalchemy.orm import sessionmaker
4from sqlmodel import Session as SQLModelSession
5from sqlmodel import create_engine
6
7engine = create_engine(...)
8SessionDB = sessionmaker(class_=SQLModelSession, autoflush=False, bind=engine)
9
10
11def get_session():
12 return SessionDB(bind=engine, expire_on_commit=False)
13
14
15@contextmanager
16def session_scope():
17 session = get_session()
18 try:
19 yield session
20 session.commit()
21 except Exception as e:
22 session.rollback()
23 raise e
24 finally:
25 session.close()
Then the corresponding usage is the very natural:
1from sqlmodel import col, select
2
3with session_scope() as session:
4 # do stuff here...for example
5 statement = (
6 select(MyTable)
7 .where(MyTable.column_name == value)
8 .order_by(col(MyTable.column_name).desc())
9 )