My info is maybe a bit dated, as it's been a while since we wrote this hackery. We also adopted SQLModel at some point but we had to patch it to work well (I think some of my contributions are now in upstream). As for some of the hacks:
def c(prop: t.Any) -> sa.Column: # type: ignore
return prop
To make it possible to access sqlmodel properties as columns for doing things like `in_` but still maintaining type safety.Added types ourselves to the base model like this:
__table__: t.ClassVar[sa.Table]
Added functions that help with typing like this: @classmethod
async def _fetch_one(cls: t.Type[BaseT], db: BaseReadOnlySqlSession, query: Select) -> t.Optional[BaseT]:
try:
return (await db.execute(query)).scalar_one()
except NoResultFound:
return None
and stuff like this for relationships: def ezrelationship(
model: t.Type[T_],
id_our: t.Union[str, sa.Column], # type: ignore
id_other: t.Optional[t.Union[t.Any, sa.Column]] = None, # type: ignore
) -> T_:
if id_other is None:
id_other = model.id
return sqlm.Relationship(sa_relationship=relationship(model, primaryjoin=f"foreign({id_our}) == {id_other}"))
def ezrelationship_back(
id_our: t.Union[str, sa.Column], # type: ignore
id_other: t.Union[str, sa.Column], # type: ignore
) -> t.Any:
model, only_id2 = id_other.split(".")
return sqlm.Relationship(
sa_relationship=relationship(
model,
primaryjoin=f"foreign({id_our}) == {id_other}_id",
back_populates=only_id2,
)
)
I hope this helps, I don't have time to find all the stuff, but we also hacked on SQLAlchemy a bit, and in other places.