No project description provided
Project description
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()
# the fields of "hero" have expired.
# Therefore, accessing them will raise MissingGreenlet error
print(hero.name)
# E sqlalchemy.exc.MissingGreenlet: greenlet_spawn has not been called;
# can't call await_only() here. Was IO attempted in an unexpected place?
# (Background on this error at: https://sqlalche.me/e/20/xd2s)
# it works!
print(await hero.awt_name) # Rusty-Man
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()
# loading lazy loading attribute will raise MissingGreenlet error
team = hero.team
# E sqlalchemy.exc.MissingGreenlet: greenlet_spawn has not been called;
# can't call await_only() here. Was IO attempted in an unexpected place?
# (Background on this error at: https://sqlalche.me/e/20/xd2s)
# it works!
team = await hero.awt_team
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Hashes for async_sqlmodel-0.1.3-py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 6ddca1acc9401fbd3a0f410dfa7ebe4810ab75dbe78bb4eb01fa1e2042b5b7d2 |
|
MD5 | 400c4a88b49576d0197d32fa5d053117 |
|
BLAKE2b-256 | 190409d0a651fef96216de46d8821e735d13ecb8c94cd069dd8ec2f13636d1c0 |