feat: initial support for dogpile caching#636
Merged
Conversation
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #636 +/- ##
==========================================
- Coverage 80.92% 79.09% -1.83%
==========================================
Files 94 99 +5
Lines 6977 7861 +884
Branches 910 1065 +155
==========================================
+ Hits 5646 6218 +572
- Misses 1042 1301 +259
- Partials 289 342 +53 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
- Remove banned `from __future__ import annotations` imports - Fix union syntax to use Optional/Union instead of X | Y - Add proper docstrings replacing inline comments - Move non-circular imports to top-level - Add cache module documentation (usage guide and API reference) - Quote forward references for TYPE_CHECKING imports
- Add missing use_cache parameter to get() method signature - Add bind_group documentation to list() and list_and_count() docstrings - Add missing TYPE_CHECKING imports for AsyncSession, scoped_session, async_scoped_session, and CacheManager in _listeners.py - Add __init__.py to tests/unit/test_cache/ directory
- Add SyncCacheRegionProtocol for sync cache region interface - Add AsyncCacheRegionProtocol for async cache region interface - Add NO_VALUE sentinel to _null.py exports - Add _cache_manager class attribute to repository classes - Fix pyright/mypy ignore comment placement on dogpile imports - Update manager.py to use SyncCacheRegionProtocol
… operations and introduce integration tests.
…` imports and reformat long lines in cache integration tests for readability.
…e` extra, including its transitive dependencies `decorator` and `stevedore`.
…ng errors when the attribute is missing.
This was referenced May 12, 2026
Bug:
cache_config field documented on SQLAlchemyAsyncConfig/SQLAlchemySyncConfig does not exist
#730
Closed
cofin
pushed a commit
to hasansezertasan/advanced-alchemy
that referenced
this pull request
May 23, 2026
Closes litestar-org#730. The dogpile.cache integration (litestar-org#636) added the `advanced_alchemy.cache` package, listeners, and repository wiring, but never extended `SQLAlchemyAsyncConfig` / `SQLAlchemySyncConfig` with the `cache_config` kwarg that the caching guide promotes. Every example in `docs/usage/caching.rst` raised `TypeError` because the field did not exist. This adds `cache_config: Optional[CacheConfig]` and `cache_manager: Optional[CacheManager]` to `GenericSQLAlchemyConfig`. `__post_init__` builds a `CacheManager` from `cache_config` when one is not supplied explicitly, then publishes it to sessions via `session_config.info["cache_manager"]` so repositories pick it up through the existing `session.info.get("cache_manager")` path. `session_config` and its `info` dict are now shallow-copied during `__post_init__` so two configs constructed with the same `session_config` instance no longer alias each other's cache_manager or `file_object_raise_on_error` flag. `__hash__` also includes `id(cache_manager)` so configs that differ only by cache region remain distinguishable in the class-level registries. Imports of `CacheConfig` / `CacheManager` are lazy: only typed under TYPE_CHECKING at module load, and only imported at runtime inside `__post_init__` when `cache_config` is set, so dogpile.cache probing is still avoided for configs that don't opt in.
cofin
added a commit
that referenced
this pull request
May 23, 2026
Closes #730. ## Summary - `SQLAlchemyAsyncConfig` and `SQLAlchemySyncConfig` now accept `cache_config: Optional[CacheConfig]` and `cache_manager: Optional[CacheManager]` kwargs, closing the documentation/implementation gap from #636. - When `cache_config` is set, `__post_init__` instantiates a `CacheManager` (unless one was passed explicitly) and publishes it to sessions via `session_config.info["cache_manager"]`. Repositories pick it up automatically through the existing `session.info.get("cache_manager")` lookup in `repository/_async.py` and `repository/_sync.py`. - `session_config` and its `info` dict are shallow-copied during `__post_init__`, so two configs constructed with the same `session_config` instance no longer alias each other's `cache_manager` or `file_object_raise_on_error` flag. - `__hash__` now includes `id(cache_manager)` so configs that differ only by cache region remain distinguishable in the class-level engine/session registries. - `CacheConfig` / `CacheManager` stay behind `TYPE_CHECKING` at module load and are imported at runtime only when `cache_config` is set, so dogpile.cache probing is still avoided for users who don't opt in. After this change the "Quick Start" and "Repository Integration" examples in `docs/usage/caching.rst` work as documented: ```python db_config = SQLAlchemyAsyncConfig( connection_string="sqlite+aiosqlite:///app.db", cache_config=CacheConfig( backend="dogpile.cache.memory", expiration_time=300, ), ) async with db_config.get_session() as session: repo = UserRepository(session=session, auto_expunge=True) user = await repo.get(user_id) # DB + cache populate user = await repo.get(user_id) # cache hit (fresh deserialized instance) ``` > [!NOTE] > `auto_expunge=True` on the repository is required for cache hits to round-trip cleanly across consecutive calls — without it, a cached entity attached to a closed session triggers `MissingGreenlet` on attribute refresh in async usage. This matches the existing "Recommended with caching" guidance in the caching guide; the Quick Start example in the docs should likely be updated to show it inline (follow-up). ## Test plan - [x] Repro from the issue body runs without raising on both async and sync configs. - [x] New unit tests in `tests/unit/test_config/test_{async,sync}_config.py`: - `cache_config` builds a manager and propagates it to `session_config.info`. - An explicit `cache_manager` overrides `cache_config` and is preserved by identity. - Without `cache_config`, no `cache_manager` key is published. - Two configs sharing a `session_config` do not clobber each other's `cache_manager` / `file_object_raise_on_error` and keep user-supplied `info` keys. - `__hash__` distinguishes configs that differ only by `cache_manager`. - [x] New integration tests in `tests/integration/test_cache_repository.py` covering both sync and async paths: - `config.get_session()` + repository, populate cache, delete the underlying DB row, second `repo.get()` in a fresh session succeeds — proving the served value comes from the cache region rather than the database. - Documented Quick Start flow: two consecutive `repo.get()` calls in one session, second call is served from cache (fresh deserialized instance, identity differs). - [x] Existing cache/config/routing suites: 253 passed, 1 skipped (pre-existing `dogpile.cache`-absent gate). <!-- docs-preview --> <hr> 📚 Documentation preview: <a href="https://litestar-org.github.io/advanced-alchemy-docs-preview/731">https://litestar-org.github.io/advanced-alchemy-docs-preview/731</a> --------- Co-authored-by: Cody Fincher <cody@litestar.dev>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Introduce support for dogpile caching, including a new caching configuration and a null region implementation for scenarios where caching is disabled or dogpile.cache is not installed. Add unit tests to validate the caching behavior and configuration options.