Async-SQLModel
Async-SQLModel is an extension module of SQLModel,
making it compatible with asynchronous programming, especially useful when lazy-loading relational fields asynchronously.
It supports awaitable fields in SQLModel model, making access to other fields awaitable.
Available under the MIT License.
Installation
$ pip install async-sqlmodel
Usage
Create a AsyncSQLModel Model
You could create a AsyncSQLModel model like this:
from typing import Optional
from sqlmodel import Field
from async_sqlmodel import AsyncSQLModel
class Hero(AsyncSQLModel, table=True):
id: Optional[int] = Field(default=None, primary_key=True)
name: str
Add an AwaitableField
Adding an AwaitableField yields an awaitable field for the field
specified in the argument.
from typing import Optional, Awaitable
from sqlmodel import Field
from async_sqlmodel import AsyncSQLModel, AwaitableField
class Hero(AsyncSQLModel, table=True):
id: Optional[int] = Field(default=None, primary_key=True)
name: str
awt_name: Awaitable[str] = AwaitableField(field="name")
This allows fields which may be subject to lazy loading or deferred / unexpiry loading to be accessed like this:
hero = Hero(name="Rusty-Man")
async_session.add(hero)
await async_session.commit()
print(hero.name)
print(await hero.awt_name)
Use an AwaitableField with Relationship
You can use an AwaitableField with Relationship.
from typing import Optional
from collections.abc import Awaitable
from sqlmodel import Field, select
from async_sqlmodel import AsyncSQLModel, AwaitableField
class Team(AsyncSQLModel, table=True):
id: Optional[int] = Field(default=None, primary_key=True)
heroes: List["Hero"] = Relationship()
awt_heroes: Awaitable[List["Hero"]] = AwaitableField(field="heroes")
class Hero(AsyncSQLModel, table=True):
id: Optional[int] = Field(default=None, primary_key=True)
team_id: Optional[int] = Field(default=None, foreign_key="team.id")
team: Optional[Team] = Relationship(back_populates="heroes")
awt_team: Awaitable[Optional[Team]] = AwaitableField(field="team")
Using an AwaitableField with Relationship fields can resolve the issues encountered during lazy loading:
hero = (
await session.exec(select(Hero).where(Hero.id == hero_rusty_man.id))
).one()
team = hero.team
team = await hero.awt_team