Version 4.0.0 (#263)

* fix: lock_tables acquires dedicated session to enforce RAII lock boundaries (#261)

* fix: make lock_tables generic over session type (#270)

* docs: fix zensical warnings

* Version 4.0.0

* docs: add v4 migration + fix lock_tables documentation
This commit is contained in:
d3vyce
2026-05-08 13:04:24 +02:00
committed by GitHub
parent 99eabe3b23
commit 189e9e1a13
13 changed files with 170 additions and 101 deletions
+23 -6
View File
@@ -7,6 +7,7 @@ from unittest.mock import patch
import pytest
from sqlalchemy import String
from sqlalchemy.ext.asyncio import async_sessionmaker, create_async_engine
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column
import fastapi_toolsets.models.watched as _watched_module
@@ -20,6 +21,7 @@ from fastapi_toolsets.models import (
listens_for,
)
from fastapi_toolsets.models.watched import (
EventSession,
_EVENT_HANDLERS,
_SESSION_CREATES,
_SESSION_DELETES,
@@ -338,6 +340,23 @@ async def mixin_session_expire():
yield session
@pytest.fixture(scope="function")
async def mixin_session_maker():
"""Provide an EventSession-backed session factory with MixinBase tables."""
engine = create_async_engine(DATABASE_URL, echo=False)
async with engine.begin() as conn:
await conn.run_sync(MixinBase.metadata.create_all)
factory = async_sessionmaker(engine, expire_on_commit=False, class_=EventSession)
try:
yield factory
finally:
async with engine.begin() as conn:
await conn.run_sync(MixinBase.metadata.drop_all)
await engine.dispose()
class TestUUIDMixin:
@pytest.mark.anyio
async def test_uuid_generated_by_db(self, mixin_session):
@@ -1559,15 +1578,13 @@ class TestEventSessionWithGetTransaction:
assert creates[0]["obj_id"] == survivor.id
@pytest.mark.anyio
async def test_lock_tables_with_events(self, mixin_session):
"""Events fire correctly after lock_tables context."""
async def test_lock_tables_with_events(self, mixin_session_maker):
"""Events fire correctly when lock_tables commits on context exit."""
from fastapi_toolsets.db import lock_tables
async with lock_tables(mixin_session, [WatchedModel]):
async with lock_tables(mixin_session_maker, [WatchedModel]) as session:
obj = WatchedModel(status="locked", other="x")
mixin_session.add(obj)
await mixin_session.commit()
session.add(obj)
creates = [e for e in _test_events if e["event"] == "create"]
assert len(creates) == 1