You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I used the GitHub search to find a similar question and didn't find it.
I searched the SQLModel documentation, with the integrated search.
I already searched in Google "How to X in SQLModel" and didn't find any information.
I already read and followed all the tutorial in the docs and didn't find an answer.
I already checked if it is not related to SQLModel but to Pydantic.
I already checked if it is not related to SQLModel but to SQLAlchemy.
Commit to Help
I commit to help with one of those options 👆
Example Code
"""Sample to show issues between Session and AsyncSession.# Setup environmentuv init sqlmodel-link-tablecd sqlmodel-link-tableuv venvsource .venv/bin/activateuv pip install sqlmodel aiosqlite greelet pytest pytest-asyncioCopy this file to sqlmodel-link-table/test_session.py and run pytest. $ pytest test_session.py -v"""fromcontextlibimportasynccontextmanager, contextmanagerfromtypingimportAsyncGenerator, GeneratorfromuuidimportUUID, uuid4importpytestfromsqlalchemyimportUniqueConstraintfromsqlalchemy.ext.asyncioimportAsyncSession, async_sessionmaker, create_async_enginefromsqlmodelimportField, Relationship, Session, SQLModel, create_engineclassLinkOrgUser(SQLModel, table=True):
"""Roles a user has in an Organization."""__tablename__: str="organization_user"# type: ignoreorg_id: UUID|None=Field(
default=None, foreign_key="organization.id", primary_key=True
)
user_id: UUID|None=Field(default=None, foreign_key="user.id", primary_key=True)
role: int# enum.IntFlagorg: "Organization"=Relationship(back_populates="users")
user: "User"=Relationship(back_populates="orgs")
classUser(SQLModel, table=True):
"""User with relationships."""__table_args__= (UniqueConstraint("email"),)
id: UUID=Field(primary_key=True, default_factory=uuid4)
name: str=Field(max_length=64)
email: str|None=Field(default=None, max_length=255)
# Relationshipsorgs: list[LinkOrgUser] =Relationship(
back_populates="user",
)
classOrganization(SQLModel, table=True):
"""Organization with users."""id: UUID=Field(primary_key=True, default_factory=uuid4)
name: str=Field(max_length=80)
users: list[LinkOrgUser] =Relationship(back_populates="org")
############################################################# pytest with synchronous database session ##@contextmanagerdefmemory_session() ->Generator[Session]:
"""Syncronious database session."""engine=create_engine("sqlite://", connect_args={"check_same_thread": False})
SQLModel.metadata.create_all(bind=engine)
withSession(engine) assession:
yieldsessiondeftest_link_sync():
withmemory_session() assession:
org=Organization(name="Example", id=UUID(int=1))
aa=User(name="AA", id=UUID(int=2))
org.users.append(LinkOrgUser(org=org, user=aa, role=1))
session.add(org)
session.commit()
assertorg.name=="Example"assert1==len(org.users)
assertaa.idin [_.user.idfor_inorg.users]
############################################################# pytest with asynchronous database session ##@asynccontextmanagerasyncdefasync_memory_session() ->AsyncGenerator[AsyncSession]:
"""Async database session."""url="sqlite+aiosqlite:///:memory:"engine=create_async_engine(url, echo=False, future=True)
asyncwithasync_sessionmaker(engine, expire_on_commit=False)() assession:
asyncwithengine.begin() asconn:
awaitconn.run_sync(SQLModel.metadata.create_all)
try:
yieldsessionfinally:
print(f"{url} finished.")
awaitengine.dispose()
@pytest.mark.asyncioasyncdeftest_link_async():
asyncwithasync_memory_session() asasync_session:
org=Organization(name="Example", id=UUID(int=5))
aa=User(name="AA", id=UUID(int=6))
org.users.append(LinkOrgUser(org=org, user=aa, role=1))
async_session.add(org)
awaitasync_session.commit()
assertorg.name=="Example"assert1==len(org.users)
assertaa.idin [_.user.idfor_inorg.users]
Description
I create an Organization and User objects. I then create a link table object using the two objects and the user's role. I commit and check the number of users in the Organization.users object.
I expect to see one user, which I do when using a synchronous database session. However under an asynchronous database session, I see two duplicates.
assert 1 == len(org.users)
E AssertionError: assert 1 == 2
E + where 2 = len([LinkOrgUser(role=1, >org_id=UUID('...005'), user_id=UUID('...006')), LinkOrgUser(role=1, >org_id=UUID('...005'), user_id=UUID('...006'))])
E + where [LinkOrgUser(role=1, org_id=UUID('...005'), user_id=UUID('...006')), LinkOrgUser(role=1, org_id=UUID('...005'), user_id=UUID('...006'))] = Organization(id=UUID('...005'), name='Example').users
There are no errors other than the assert in the failed test. I don't understand why one session works while the other doesn't. I must be doing something wrong, but what?
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
-
First Check
Commit to Help
Example Code
Description
I create an Organization and User objects. I then create a link table object using the two objects and the user's role. I commit and check the number of users in the Organization.users object.
I expect to see one user, which I do when using a synchronous database session. However under an asynchronous database session, I see two duplicates.
There are no errors other than the assert in the failed test. I don't understand why one session works while the other doesn't. I must be doing something wrong, but what?
Operating System
Linux
Operating System Details
Up to date Arch
SQLModel Version
0.0.22
Python Version
3.13.0
Additional Context
Package Version
aiosqlite 0.20.0
annotated-types 0.7.0
greenlet 3.1.1
iniconfig 2.0.0
packaging 24.2
pluggy 1.5.0
pydantic 2.9.2
pydantic-core 2.23.4
pytest 8.3.3
pytest-asyncio 0.24.0
sqlalchemy 2.0.36
sqlmodel 0.0.22
typing-extensions 4.12.2
Beta Was this translation helpful? Give feedback.
All reactions