Skip to content

5.13.0 — 2026-10-14

← 5.14.0 | 5.12.1 → | ↑ 5.x series

Added

Adapters - SQLAlchemy

  • Count threshold - execute_search_query accepts a keyword-only count_threshold. The total is exact up to that many rows. Above it, PostgreSQL returns the planner estimate (EXPLAIN (FORMAT JSON)) instead of scanning every row. MySQL, SQLite and StarRocks still count exactly.
    • The estimate never falls below the rows already counted, and a query that cannot be estimated falls back to the exact count
  • Count cache - With COUNT_CACHE_ENABLED=true the total of a search is cached for COUNT_CACHE_TTL_SECONDS, so only the first page of a search runs a COUNT and later pages reuse the total. The sync adapters use ttl_cache and the async adapters use alru_cache, so it needs the cache extra. The cache is off by default, and a total can be stale for up to the TTL.

Configs - SQLAlchemy

  • Count settings - COUNT_CACHE_ENABLED (default false), COUNT_CACHE_TTL_SECONDS (default 60), COUNT_CACHE_MAX_SIZE (default 1000) and COUNT_THRESHOLD (default unset, always exact) are added to SQLAlchemyConfig and to .env.example for the SQLAlchemy, MySQL, SQLite and StarRocks configs.

Changed

Adapters - SQLAlchemy

  • Cheaper search totals - execute_search_query skips the COUNT when there is no pagination or the first page is not full. Otherwise the COUNT reads only the entity primary key and drops the ORDER BY, so the database can answer from the primary key index. A query with DISTINCT, GROUP BY, HAVING, LIMIT, OFFSET or FETCH keeps its own columns, because they change the row count.
  • Filter expressions - _apply_filter builds its expressions from one module-level map instead of a dict of 15 lambdas on every call. IS_NOT_NULL uses is_not.
  • Shared helpers - The sync and async adapters share the entity type checks and the entity extraction of execute_search_query, and _handle_db_exception lowers the error message once.

Tests

  • Search totals - New scenarios in atomic_transactions.feature cover totals across pages, which pages run a COUNT, DISTINCT, GROUP BY and LIMIT queries, the exact and estimated totals around the threshold, the cache keys and TTL (sync and async) and every filter operation, with the rejection of a non-list value for list filters. They run on PostgreSQL, SQLite, MySQL and StarRocks.

Chore

  • Search totals tutorial - New SQLAlchemy Search Totals tutorial, linked from the PostgreSQL, MySQL, SQLite and StarRocks tutorials and from the adapters index.