Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
174 commits
Select commit Hold shift + click to select a range
016bed6
refactor(mysql): remove unused helpers left from the mysql_common split
cofin Oct 31, 2026
bfec383
fix(mysql): map errno 1061/1091 to OperationalError and stop swallowi…
cofin Oct 31, 2026
9f2450e
fix(adapters): align store class names with the Litestar session migr…
cofin Oct 31, 2026
808c78b
fix(core,mssql_python): treat OUTPUT ... INTO as not returning client…
cofin Oct 31, 2026
5044782
fix(config): declare correlation settings on the Flask and Starlette …
cofin Oct 31, 2026
de6bb18
feat(extensions): enable correlation middleware by default in every f…
cofin Oct 31, 2026
a29b1d3
fix(sqlite,aiosqlite): correct extended constraint error codes for no…
cofin Oct 31, 2026
42f3871
fix(aiosqlite): fix pool reset retirement, cache hit exception isolat…
cofin Oct 31, 2026
5ba14d1
fix(aiosqlite): use weakref for connection tracking, add float32 embe…
cofin Oct 31, 2026
6f52244
perf(aiosqlite): optimize hot-path closures, cursor creation, and met…
cofin Oct 31, 2026
c601ffd
refactor(aiosqlite): clean up dead code, redundant wrappers, and erro…
cofin Oct 31, 2026
b007c51
fix(sqlite): fix transaction rollback on exit, reentrancy depth, shar…
cofin Oct 31, 2026
c976923
fix(sqlite): serialize float32 embeddings in ADK store and parameteri…
cofin Oct 31, 2026
e156fd5
fix(sqlite): memoize generated columns, coalesce schema to main, and …
cofin Oct 31, 2026
19db813
perf(sqlite): optimize hot paths, parameter normalization, and savepo…
cofin Oct 31, 2026
bf904d3
refactor(sqlite): clean up dead code, redundant wrappers, and connect…
cofin Oct 31, 2026
8a9b64a
fix(aiomysql): escape LOAD DATA statement percent signs and restore c…
cofin Oct 31, 2026
921e872
fix(aiomysql): batch ADK memory insertions and use cross-version MySQ…
cofin Oct 31, 2026
b6717b5
perf(aiomysql): add fast path to literal percent escaping and elimina…
cofin Oct 31, 2026
86c8f0f
refactor(aiomysql): use statement config in execution methods, delega…
cofin Oct 31, 2026
ba149bc
fix(asyncmy): restore cursor fast path for clean cached query execution
cofin Oct 31, 2026
f41dca2
fix(asyncmy): batch ADK memory insertions, escape LIKE wildcards, and…
cofin Oct 31, 2026
da7e2ec
refactor(data_dictionary): combine MySQL DDL setup scalar queries and…
cofin Oct 31, 2026
d5d1af5
perf(asyncmy): offload local infile payload write to worker thread an…
cofin Oct 31, 2026
832998b
refactor(asyncmy): improve exception mapping, guard optional driver i…
cofin Oct 31, 2026
747a8e5
fix(mysqlconnector): guard optional driver imports, preserve exceptio…
cofin Oct 31, 2026
9d63410
fix(mysqlconnector): ensure transaction rollback on commit failure, h…
cofin Oct 31, 2026
ea90311
refactor(mysqlconnector): verify cached data dictionary properties an…
cofin Oct 31, 2026
4c15a8b
perf(mysqlconnector): precompute cursor options, cache stream deseria…
cofin Oct 31, 2026
3354696
refactor(mysqlconnector): map table/column errors to OperationalError…
cofin Oct 31, 2026
f4d2370
fix(pymysql): preserve ambient exception state in stream sources and …
cofin Oct 31, 2026
bda595b
fix(pymysql): remove redundant drop index, use cross-version upsert, …
cofin Oct 31, 2026
a373766
perf(pymysql): optimize pool health check guard, cache deserializers,…
cofin Oct 31, 2026
0814120
refactor(pymysql): modernize ping calls, streamline script execution,…
cofin Oct 31, 2026
90e890e
fix(mysql): restore pymysql percent-escaping contract and repair new …
cofin Oct 31, 2026
c29200e
fix(mysql): limit the literal-percent count fast path to positional p…
cofin Oct 31, 2026
6f1db20
fix(sybase,sqlanywhere): bind Sybase and SQL Anywhere error bases to …
cofin Nov 1, 2026
afd6377
fix(mssql_python): detect implicit transactions and rollback on sessi…
cofin Nov 1, 2026
bf0d4fd
fix(db2): translate migration schema exceptions, expand SQLSTATE mapp…
cofin Nov 1, 2026
3b068c6
fix(db2): batch ADK memory entry existence checks and qualify extensi…
cofin Nov 1, 2026
b77bccd
fix(db2): remove unused query templates from Db2 catalog SQL
cofin Nov 1, 2026
c734875
perf(db2): guard stream exception handling and cache session driver r…
cofin Nov 1, 2026
767c6da
docs(db2): document schema identifier quoting in session schema reset
cofin Nov 1, 2026
f21d011
fix(mssql_python): map transaction errors, guard stream execution, an…
cofin Nov 1, 2026
d6b2434
fix(mssql_python): add HOLDLOCK to session MERGE, batch memory insert…
cofin Nov 1, 2026
abf888f
feat(mssql_python): implement missing metadata methods and modernize …
cofin Nov 1, 2026
b53d8db
perf(mssql_python): optimize cache hits and replace hot-path generato…
cofin Nov 1, 2026
059de4c
refactor(mssql_python): map ODBC SQLSTATE codes, deduplicate pool hoo…
cofin Nov 1, 2026
333e907
fix(pymssql): ensure idempotent transaction boundaries, map FreeTDS e…
cofin Nov 1, 2026
6b47557
fix(pymssql): add HOLDLOCK to session MERGE statement
cofin Nov 1, 2026
d92f0ce
feat(pymssql): implement missing data dictionary methods and moderniz…
cofin Nov 1, 2026
5a58bc5
perf(pymssql): eliminate hot-path generator allocations and allow sta…
cofin Nov 1, 2026
f335336
refactor(pymssql): track pool re-entrancy depth, guard stream executi…
cofin Nov 1, 2026
e4b0483
fix(sqlanywhere): fix ADK memory DDL, table missing handling, and Lit…
cofin Nov 1, 2026
1dced2a
fix(sqlanywhere): reconcile dialect feature flags and data dictionary…
cofin Nov 1, 2026
42a9cad
perf(sqlanywhere): isolate exception unwinding and optimize identifie…
cofin Nov 1, 2026
d5f678e
fix(sqlanywhere): raise TransactionError on transaction failures and …
cofin Nov 1, 2026
21be049
fix(sybase): map transaction exceptions through create_mapped_exception
cofin Nov 1, 2026
f1dc213
fix(sybase): map database exceptions in ADK and Litestar stores
cofin Nov 1, 2026
193b60b
perf(sybase): isolate exception unwinding and cache pymssql module re…
cofin Nov 1, 2026
6708f86
fix(sybase): resolve migration tracking table columns using USER_NAME…
cofin Nov 1, 2026
5eba752
fix(mssql,sybase,sqlanywhere): repair T-SQL family integration
cofin Nov 1, 2026
4dcf757
feat(oracledb): add and persist ADK memory embedding column
cofin Nov 1, 2026
c6d9d6b
fix(oracledb): resolve ORA-00997 on index expression catalog queries
cofin Nov 1, 2026
38a4681
fix(oracledb): correct exception handling, script parameter binding, …
cofin Nov 1, 2026
2a7bd63
fix(oracledb): remediate ADK, Litestar, and events extension stores
cofin Nov 1, 2026
3c40a27
refactor(oracledb): relocate version cache to compiled core and resol…
cofin Nov 1, 2026
1460d91
perf(oracledb): optimize hot-path allocations and lazy arrow batch st…
cofin Nov 1, 2026
c685585
refactor(oracledb): clean up error mappings, unpooled connections, DD…
cofin Nov 1, 2026
4d5b36a
fix(cockroach): gate follower reads on read-only queries and support …
cofin Nov 1, 2026
2e07be3
fix(cockroach): run user psycopg configure callback after internal setup
cofin Nov 1, 2026
24e674f
fix(asyncpg): exception mapping, transaction lifecycle, and script ex…
cofin Nov 1, 2026
40c0dfd
fix(asyncpg): ADK, Litestar, and events store enhancements
cofin Nov 1, 2026
21fa823
fix(asyncpg): data dictionary and postgres catalog query fixes
cofin Nov 1, 2026
ecf3081
perf(asyncpg): hot-path allocations and cache execution fast path
cofin Nov 1, 2026
4def74e
refactor(asyncpg): code hygiene, capability flags, and dead code cleanup
cofin Nov 1, 2026
305116d
fix(cockroach_asyncpg): fallback batched insert for storage and recor…
cofin Nov 1, 2026
862a63a
fix(cockroach_asyncpg): batch ADK memory inserts, vector search, and …
cofin Nov 1, 2026
98e301f
fix(cockroach_asyncpg): data dictionary queries and metadata consolid…
cofin Nov 1, 2026
f6d5b05
perf(cockroach_asyncpg): eliminate transient dict allocations and add…
cofin Nov 1, 2026
4d6c7c3
refactor(cockroach_asyncpg): code hygiene, timeouts, and typing cleanup
cofin Nov 1, 2026
fb3572f
fix(cockroach_psycopg): batch ADK memory inserts, vector search, and …
cofin Nov 1, 2026
87f8fbe
fix(cockroach_psycopg): data dictionary queries and metadata consolid…
cofin Nov 1, 2026
ed383a7
perf(cockroach_psycopg): cache validated default_staleness and optimi…
cofin Nov 1, 2026
d220404
refactor(cockroach_psycopg): code hygiene, connection typing, and nat…
cofin Nov 1, 2026
1c78cf0
fix(psqlpy): correct exception mapping, parameter binding, and transa…
cofin Nov 1, 2026
eb0eac8
fix(psqlpy): remediate ADK, Litestar, and events stores
cofin Nov 1, 2026
c1c7623
fix(psqlpy): correct data dictionary and catalog queries
cofin Nov 1, 2026
93ff6ec
perf(psqlpy): reduce hot-path allocations and add cache-hit fast path
cofin Nov 1, 2026
20d3a67
refactor(psqlpy): clean up structure, naming, and dead code
cofin Nov 1, 2026
8a393e9
fix(psycopg): correct exception mapping, parameter binding, and trans…
cofin Nov 1, 2026
a79400d
fix(psycopg): remediate ADK, Litestar, and events stores
cofin Nov 1, 2026
093a95d
fix(psycopg): correct data dictionary and catalog queries
cofin Nov 1, 2026
cfedb29
perf(psycopg): optimize cache hit wire escaping, transaction status c…
cofin Nov 1, 2026
761c3f9
refactor(psycopg): clean up error mappings, driver telemetry, types, …
cofin Nov 1, 2026
879e728
fix(adapters): repair family integration regressions
cofin Nov 1, 2026
b64df0c
refactor(sybase,sqlanywhere,db2): remove empty extension config classes
cofin Nov 1, 2026
f693dc3
refactor(adapters): normalize pooling driver_features names
cofin Nov 1, 2026
ce4cfc5
refactor(adapters): import each adapter's driver eagerly
cofin Nov 1, 2026
971692c
fix(adbc): handle autocommit in transactions, status codes, and state…
cofin Nov 1, 2026
8eacd01
fix(adbc): harden litestar session and adk memory store operations
cofin Nov 1, 2026
02d245c
fix(adbc): safeguard Snowflake index metadata and retain empty foreig…
cofin Nov 1, 2026
322175e
perf(adbc): eliminate heap allocation and boxings in uuid rewriting a…
cofin Nov 1, 2026
b5a2860
refactor(adbc): consolidate driver features, isolation, and stream ch…
cofin Nov 1, 2026
f5e400a
fix(arrow_odbc): isolate ambient exceptions, map ArrowException, and …
cofin Nov 1, 2026
6cba38e
fix(arrow_odbc): ensure atomic writes begin transactions on MSSQL and…
cofin Nov 1, 2026
bd65e79
fix(arrow_odbc): report supported metadata capabilities for all catal…
cofin Nov 1, 2026
c34bfd9
perf(arrow_odbc): eliminate kwargs dict allocation in batch reading a…
cofin Nov 1, 2026
ff1c66b
refactor(arrow_odbc): align chunk_size docstring with default impleme…
cofin Nov 1, 2026
030bc0f
fix(bigquery): map RetryError, catch GoogleAPIError, and handle empty…
cofin Nov 1, 2026
30a1a3b
refactor(bigquery): consolidate extension partition clauses and remov…
cofin Nov 1, 2026
40d46a9
perf(bigquery): isolate ambient exceptions and bind none_type constan…
cofin Nov 1, 2026
1975493
refactor(bigquery): preserve causes, consolidate dataset resolution, …
cofin Nov 1, 2026
88a42f1
fix(duckdb): handle divergent stream types, AST mutation, native exce…
cofin Nov 1, 2026
f089e5b
refactor(duckdb): modernize typing, guard embedding search, and suppo…
cofin Nov 1, 2026
39f8316
feat(duckdb): implement metadata capabilities and wire catalog queries
cofin Nov 1, 2026
b944ff9
perf(duckdb): eliminate closures, precompute secret checks, avoid dou…
cofin Nov 1, 2026
a79290d
refactor(duckdb): isolate auxiliary exceptions, clean temporary profi…
cofin Nov 1, 2026
41b41fa
fix(spanner): guard transaction ownership, map batch status, and catc…
cofin Nov 1, 2026
72a7ffd
refactor(spanner): single-statement upsert, partitioned cleanup, ddl …
cofin Nov 1, 2026
4d17e5e
refactor(spanner): wrap None filter parameters in TypedParameter, con…
cofin Nov 1, 2026
48f6e0b
perf(spanner): copy-on-write coercion, eliminate generator allocation…
cofin Nov 1, 2026
4d54998
refactor(spanner): concurrency-safe options, robust byte decoding, ar…
cofin Nov 1, 2026
2ef4cd4
refactor(adapters): enforce one import contract across adapters
cofin Nov 1, 2026
04ec9aa
refactor(adapters): normalize columnar driver_features names and decl…
cofin Nov 1, 2026
8f8c4b8
test(sqlanywhere): add integration driver test suite with hermetic cl…
cofin Nov 1, 2026
607e77a
test(sqlanywhere): consume upstream pytest-databases client library f…
cofin Nov 1, 2026
2ee22f8
fix(adapters): preserve transaction, streaming, and configuration con…
cofin Nov 1, 2026
2800a73
chore: bump deps
cofin Nov 1, 2026
179ee75
fix(adbc): release acquisitions when session setup fails
cofin Nov 1, 2026
57953f3
feat(adbc): add bounded exclusive PostgreSQL connection leases
cofin Nov 1, 2026
822c4ab
feat(adbc): reset and drain reusable PostgreSQL leases
cofin Nov 1, 2026
af40842
fix(adbc): close lazy stream resources before session release
cofin Nov 1, 2026
0dc22b0
feat(adbc): expose opt-in PostgreSQL pool configuration
cofin Nov 1, 2026
f12a8f2
test(adbc): verify native PostgreSQL pool isolation and lifetime
cofin Nov 1, 2026
3acf28e
docs(adbc): document pooling and add transactional benchmark
cofin Nov 1, 2026
1290122
fix(adbc): preserve serializer identity in a bounded converter cache
cofin Nov 1, 2026
c9ba2cc
fix(core): exclude returning targets from client row results
cofin Nov 1, 2026
0e794a8
docs(sanic): correct the correlation middleware default
cofin Nov 1, 2026
a0fb310
fix(asyncmy): retain ingestion payload ownership during cancellation
cofin Nov 1, 2026
eb7e8ca
fix(adbc): preserve pool validation in compiled builds
cofin Nov 1, 2026
8f150d6
fix(oracledb): close standalone connections after initialization failure
cofin Nov 1, 2026
2dc0019
fix(spanner): preserve checkout cleanup and stream exception mapping
cofin Nov 1, 2026
b3f10b6
fix(mssql): scope table details to the requested table
cofin Nov 1, 2026
8f552fa
fix(pymssql): retain nesting state after failed acquisition
cofin Nov 1, 2026
04114c3
fix(psqlpy): stop Arrow ingestion after the first copy failure
cofin Nov 1, 2026
5f49bb2
fix(cockroach): preserve configure callbacks in derived pools
cofin Nov 1, 2026
ba3148a
fix(adbc): preserve memory event deduplication across batch conflicts
cofin Nov 1, 2026
7023c68
fix(psqlpy): preserve native owner types in memory batches
cofin Nov 1, 2026
76cf1f3
fix(cockroach): preserve memory schema and owner contracts
cofin Nov 1, 2026
9fb7452
test(adapters): remove source scanners and deletion-only assertions
cofin Nov 1, 2026
044a5f2
test(adapters): type SDK stand-ins and mixed async results accurately
cofin Nov 1, 2026
0834044
fix(adbc): honor native autocommit transaction boundaries
cofin Nov 1, 2026
05f6c92
test(adapters): align catalog and stream stand-ins with native types
cofin Nov 1, 2026
c456859
fix(core): reconstruct parameter declarations during serialization
cofin Nov 1, 2026
a4fb997
fix(builder): normalize native foreign key metadata explicitly
cofin Nov 1, 2026
7f85a17
fix(driver): consume callback profiling state across compiled boundaries
cofin Nov 1, 2026
508204a
test(core): verify public behavior in installed compiled packages
cofin Nov 1, 2026
c9da2c8
test(adbc): exercise external dependencies and configured behavior
cofin Nov 1, 2026
3a44d28
test(pools): simulate health checks through external SDKs
cofin Nov 1, 2026
1cc37ad
refactor(types): use the public data dictionary facade across packages
cofin Nov 1, 2026
ec347e3
fix(db2): restore exception state after async health checks
cofin Nov 1, 2026
ee5a965
fix(driver): dispatch DDL hooks through interpreted overrides
cofin Nov 1, 2026
1b6333e
fix(postgres): restore client exports and search-path index metadata
cofin Nov 2, 2026
8973fc4
test(db2): cover native isolation and typed metadata contracts
cofin Nov 2, 2026
7ab1f76
fix(ci): keep SQL Anywhere SDK optional in wheel smoke
cofin Nov 2, 2026
b0fd19e
fix(oracledb): restore stack and index metadata with unified version …
cofin Nov 2, 2026
4bcb0ee
test(db2): execute native Arrow-ODBC with isolated client runtime
cofin Nov 2, 2026
5078352
docs(data-dictionary): refresh corrected catalog query references
cofin Nov 2, 2026
0b77930
fix(db2): apply schema values without SDK DSN truncation
cofin Nov 2, 2026
9991923
fix(ci): keep Sybase SDK optional in clean wheel smoke
cofin Nov 2, 2026
2e90dea
test(db2): resolve physical Python paths in ODBC runtime
cofin Nov 2, 2026
3d5ae9d
test(db2): enable native injected-pool lifecycle contracts
cofin Nov 2, 2026
c5e844b
test(adapters): use dialect-aware injected-pool probes
cofin Nov 2, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
67 changes: 65 additions & 2 deletions docs/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ important operational fixes.

**Added:**

* Added a pool for the native PostgreSQL ADBC driver. Set `AdbcConfig(pool_config={})` to reuse connections. Each lease has a wait timeout; each return clears session state. Pooling is off by default. See the [ADBC guide](databases/adbc.md#postgresql-connection-reuse) for supported settings.

* Added Sybase Adaptive Server Enterprise (`sqlspec.adapters.sybase` with `SybaseSyncConfig` and `SybaseSyncDriver`) and SAP SQL Anywhere (`sqlspec.adapters.sqlanywhere` with `SqlAnywhereSyncConfig` and `SqlAnywhereSyncDriver`) database adapters, custom SQLGlot dialects (`Sybase` and `SQLAnywhere` in `sqlspec.dialects.sybase`), data dictionaries (`SybaseSyncDataDictionary` and `SqlAnywhereSyncDataDictionary` with `SYBASE_CONFIG` and `SQLANYWHERE_CONFIG`), type converters (`SybaseOutputConverter` and `SqlAnywhereOutputConverter`), and extension stores for Litestar sessions (`SybaseStore`, `SqlAnywhereStore`), Event queues (`SybaseEventQueueStore`, `SqlAnywhereEventQueueStore`), and Google ADK sessions and memory (`SybaseADKStore`, `SybaseADKMemoryStore`, `SqlAnywhereADKStore`, `SqlAnywhereADKMemoryStore`).
([#870](https://github.com/litestar-org/sqlspec/pull/870))
* Added `arrow_odbc` dialect auto-detection and `information_schema` / system catalog introspection for Sybase ASE (`Adaptive Server Enterprise` / `ASE`) and SAP SQL Anywhere (`SQL Anywhere` / `Sybase IQ`), routing detected connections to the `sybase` and `sqlanywhere` data dictionaries.
Expand All @@ -25,24 +27,85 @@ important operational fixes.

**Changed:**

* Replaced correlated per-column scalar subqueries in data dictionary `columns.sql` and `indexes.sql` catalog queries across `postgres`, `cockroach`, `mssql`, `mysql`, `oracle`, `db2`, and `duckdb` with pre-aggregated CTEs and joins, and reduced `ColumnMetadata` to its 18 core catalog fields.

* Renamed public Litestar stores: `SQLiteStore` to `SqliteStore`, `ADBCStore` to `AdbcStore`, and `DuckdbStore` to `DuckDBStore`. Update imports and store construction accordingly. DuckDB ADK exports likewise use `DuckDBADKStore`, `DuckDBADKMemoryStore`, `DuckDBADKConfig`, and `DuckDBADKFTSOptions` instead of their `Duckdb` spellings.

* Removed `SybaseSyncEventQueueStore` and `SqlanywhereSyncEventQueueStore`; use `SybaseEventQueueStore` and `SqlanywhereEventQueueStore` respectively.

* Standardized database failures as SQLSpec exceptions across statement execution, cached queries, bulk loads, and transaction boundaries. Code catching native driver errors should catch the corresponding `sqlspec.exceptions` classes instead. Constraint violations retain specific classes such as `UniqueViolationError` and `ForeignKeyViolationError`; syntax errors raise `SQLParsingError`. MySQL errors 1061 and 1091 now raise `OperationalError` instead of being suppressed. Original driver exceptions remain available as causes when the driver supplies an exception object.

* Changed default SQLite `:memory:` pools to share one database across connections within that pool. Shared cache does not enable dirty reads by default; applications that deliberately need dirty reads must explicitly configure `read_uncommitted`.

* Successful Psycopg `on_connection_create` hooks now commit their setup transaction before a connection enters the pool. Session settings such as `search_path` and timezone persist, and failed setup is rolled back. Hooks must not rely on their writes remaining uncommitted.

* ADK table-name validation now rejects schema or dataset qualifiers where the selected adapter cannot generate valid qualified DDL. Supported schema-qualified stores retain that capability.

* ADK schema changes target newly initialized stores. Existing ADK tables must be reset and recreated for this release; resetting removes their stored sessions and memories. Upgrade migrations for these schema changes are deferred.

* Removed legacy `pgbouncer` and `pgbouncer_mode` flags from PostgreSQL driver features across `asyncpg`, `psycopg`, and `psqlpy` in favor of canonical `pooler_mode="transaction"`.

* Removed the `pgbouncer` key from `AsyncpgConnectionConfig`; set `driver_features={"pooler_mode": "transaction"}` instead.

* Removed the empty `SybaseADKConfig`, `SqlanywhereADKConfig`, `Db2LitestarConfig`, and `Db2EventsConfig` TypedDicts; use the base `ADKConfig`, `LitestarConfig`, and `EventsConfig`.

* Renamed `use_pool` to `enable_pooling` (default `True`) across `mssql_python` and `pymssql` driver features.

* Renamed `arrow_odbc` `enable_driver_pooling` to `enable_pooling` and BigQuery `use_query_and_wait` to `enable_query_and_wait`.

* Removed the ADBC `strict_type_coercion` and `arrow_extension_types` driver feature aliases; use `enable_strict_type_coercion` and `enable_arrow_extension_types`.

* Declared driver feature keys that adapters already read: `events_backend` on `ArrowOdbcDriverFeatures` and `default_query_job_config` on `BigQueryDriverFeatures`.

* Replaced `null_pool` in `psycopg` connection configuration and driver features with canonical `enable_pooling=False`.

* Defaulted `enable_correlation_middleware` to `True` across all web framework extensions (`Litestar`, `FastAPI`, `Starlette`, `Sanic`, `Flask`).

* Standardized adapter driver imports: importing `sqlspec.adapters.<name>` eagerly imports that adapter's driver, raising the native `ModuleNotFoundError` when the driver is not installed, while non-driver optional dependencies load on first use.

* Documented Oracle AQ dequeue commit behavior as at-most-once delivery.

* Added SAP SQL Anywhere integration driver test suite with hermetic in-container client runtime extraction.

* Replaced correlated per-column scalar subqueries in data dictionary `columns.sql` and `indexes.sql` catalog queries across `postgres`, `cockroach`, `mysql`, `oracle`, `db2`, and `duckdb` with pre-aggregated CTEs and joins, and reduced `ColumnMetadata` to its 18 core catalog fields.
([#866](https://github.com/litestar-org/sqlspec/pull/866))

* Redesigned the documentation site architecture around Zensical and `mkdocstrings-python` with Diataxis-aligned navigation (`Getting Started`, `Learn`, `Adapters`, `Extensions`, `Examples`, `Reference`), interactive WebAssembly SQL playground, runnable `docs/examples/` snippets, conceptual Mermaid diagrams, and tabbed package manager and `SQLFileLoader` examples.
([#864](https://github.com/litestar-org/sqlspec/pull/864),
[#867](https://github.com/litestar-org/sqlspec/pull/867),
[#869](https://github.com/litestar-org/sqlspec/pull/869))

* Migrated integration test infrastructure to clientless `pytest-databases` fixtures (`#859`).
([#859](https://github.com/litestar-org/sqlspec/pull/859))

* Upgraded CI GitHub Actions `astral-sh/setup-uv` from `10.3.1` to `10.3.3` and pinned `actions/checkout` (`6.0.2`), `actions/setup-python` (`7.1.0`), `actions/cache` (`6.0.0`), and `actions/upload-pages-artifact` / `actions/deploy-pages` in `.github/workflows/ci.yml` and `.github/workflows/docs.yml`.
([#872](https://github.com/litestar-org/sqlspec/pull/872))

**Fixed:**


* ADBC now closes its own connections if a hook, profile setup, driver setup, or session setup fails. It keeps the first error and leaves supplied connections open.

* Explicit ADBC transactions now honor native `autocommit=True` on supported drivers. If rollback cleanup fails, autocommit stays off so mode restoration cannot commit pending writes.

* Preserved supported Arrow conversion and mutation paths for Asyncmy and Spanner while reporting their native capabilities accurately; corrected ADBC lowercase readers, DuckDB stream ownership and table filtering, and SQL Server Arrow cursor lifetimes.

* Corrected Oracle session-renewal bindings, pipeline error conversion, ADK batch-error handling, standalone connection setup, and deferred Arrow failures. Text-only Oracle memory stores remain available on servers without native vector support.

* Preserved PostgreSQL cache-hit query semantics, affected-row counts, mapped exceptions, JSON scalar values, and ADK embeddings. Psycopg connection hooks leave pooled connections idle, COPY finalization errors are translated, and Asyncpg continue-on-error stacks recover through savepoints inside caller transactions.

* Preserved SQL Server 2016 constraint and index metadata queries with compatible catalog aggregation.

* Corrected SQL Anywhere implicit-transaction cleanup, Db2 ADK index-name matching and event deduplication, MySQL batch percent escaping, optional Connector/Python async-pool imports, privilege filters, and mutable DDL capture settings.

* Removed runtime `duckdb` imports from `sqlspec.adapters.adbc` (`AdbcDataDictionary` and `sqlspec/adapters/adbc/core.py`) and enforced strict adapter import isolation across all 20 database adapters in `tests/unit/test_import_time.py`.
([#865](https://github.com/litestar-org/sqlspec/pull/865))

* Eliminated extra row copies and `UserWarning` in `DuckDBDriver.select_to_arrow` on DuckDB 2.0+ by routing parameterless `SELECT` queries through `connection.sql(query).to_arrow_table()` and `to_arrow_reader(batch_size=...)` when no open DB-API transaction is active on the connection.

* Fixed `compile_table_ddl_results` and `CreateIndex` cross-dialect DDL synthesis to emit `COMMENT ON` only on dialects that support it (`postgres`, `oracle`, `db2`, `duckdb`, `snowflake`), inline `COMMENT` clauses on `mysql` and `mariadb`, render `STORING (...)` on `spanner` and `spangres`, fold unquoted source identifiers to target case before quoting target-only reserved keywords, and preserve SQLite `NUMERIC` type affinity.

* Fixed `MigrationSquasher.fold_canonical_ddl` to fall back cleanly to raw statement concatenation when a migration contains interleaved DML or procedural blocks (`INSERT`, `UPDATE`, `DELETE`, `MERGE`, `COPY`, `DO`, `CALL`), preserve table-level constraints across `ALTER TABLE ... RENAME COLUMN` and `DROP COLUMN`, and update `sqlspec_migrations` tracker history atomically inside a single transaction when applying squashed migrations.

* Fixed `write_fixture_shards` to unlink stale shard and legacy single-file artifacts (`<table>.json`, `<table>.json.gz`, and higher-numbered shards) before writing new shards so subsequent `load_fixture` calls do not read orphaned records.

### v0.69.0 - Oracle PKCS#12 wallet conversion, TNS alias resolution, proximity RRF, and server-side DBMS_CLOUD ingestion
Expand Down Expand Up @@ -260,7 +323,7 @@ important operational fixes.
savepoints, SQLSTATE/vendor exception mapping, and default
`enable_lowercase_column_names=True` normalization for Oracle and Db2.
([#839](https://github.com/litestar-org/sqlspec/pull/839))
* `ADBCStore` (Litestar sessions), `AdbcEventQueueStore` (event channels),
* `AdbcStore` (Litestar sessions), `AdbcEventQueueStore` (event channels),
`AdbcADKStore`, and `AdbcADKMemoryStore` (Google ADK sessions and memory)
add Oracle (`oracle`) and IBM Db2 (`db2`) backend support with idempotent
DDL guards (PL/SQL `SQLCODE` blocks for Oracle and `SYSCAT` catalog probes
Expand Down
12 changes: 12 additions & 0 deletions docs/contributing/creating-adapters.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,18 @@ sqlspec/adapters/<name>/
- **`driver.py`**: Subclasses `SyncDriverAdapterBase` or `AsyncDriverAdapterBase`, implementing `dispatch_execute`, `dispatch_execute_many`, `dispatch_execute_script`, `begin`, `commit`, `rollback`, `with_cursor`, `handle_database_exceptions`, `_connection_in_transaction`, and `data_dictionary`.
- **`data_dictionary.py`**: Subclasses `SyncDataDictionaryBase` or `AsyncDataDictionaryBase`, binding the dialect's SQL query pack from `sqlspec/data_dictionary/dialects/<dialect>/` to introspect tables, columns, indexes, foreign keys, and server versions.

## Import Contract

Every driver is optional: users install only the extras for the adapters they use, and any one adapter (or all of them) works without the other drivers installed. Each adapter follows the same import rules:

- **Own driver, imported eagerly.** `import sqlspec.adapters.<name>` imports that adapter's driver once, at the top of `_typing.py`, as aliased re-exports (`from asyncpg import Connection as AsyncpgRawConnection`). A missing driver raises the driver's own `ModuleNotFoundError`. Do not wrap the adapter's own driver in `import_optional`, `import_optional_attr`, `importlib.import_module`, `try`/`except ImportError` fallbacks, `None` placeholders, stub classes, or a module `__getattr__`.
- **No other drivers.** An adapter never imports another adapter's driver or package. The CockroachDB adapters wrapping `asyncpg` and `psycopg` are the only allowed cross-adapter imports.
- **One source of driver names.** `config.py`, `core.py`, `driver.py`, `pool.py`, and the extension stores import driver names from `_typing`, not from the driver package.
- **One `TYPE_CHECKING` block.** `_typing.py` uses a single `if TYPE_CHECKING: ... else: ...` block, only for subscripted generics (`Pool[Record]`), `Protocol` types for compiled driver classes, sqlspec imports that would be circular, and secondary optional types.
- **Secondary dependencies through the shared shim.** When code cannot avoid referencing an optional dependency at import time (a runtime-evaluated annotation, an `isinstance` target, or an availability check), import the type or flag from `sqlspec.typing` (for example `ArrowTable`, `NumpyArray`, `PYARROW_INSTALLED`, `PGVECTOR_INSTALLED`). `sqlspec/_typing.py` resolves these lazily and supplies protocol fallbacks when the package is absent. If the shim lacks a type or flag you need, add it there instead of writing a local fallback. When the module itself is needed (`pyarrow`, `pandas`, `polars`, `numpy`, `pgvector`, `rich`, cloud connectors, storage backends, observability packages), load it inside the function that uses it (`ensure_*` when required, `import_optional` when there is a fallback), never at module import.

Register a new adapter's driver module(s) in `ADAPTER_DRIVERS` in `tests/unit/test_import_time.py`. The import-contract tests fail for unregistered adapters and check that the adapter raises the driver's own error when the driver is missing, imports with every other driver blocked, and loads no secondary optional module at import. If the driver package itself imports an optional module, list it in `DRIVER_OWNED_OPTIONAL_IMPORTS` with the reason. For development, add the driver to the `extras` dependency group in `pyproject.toml`; dependency groups are not published to PyPI.

## The `apply_driver_features` Contract

Each adapter's `core.py` normalizes user-supplied `driver_features` and applies custom JSON serializers or type converters to the adapter's `StatementConfig`:
Expand Down
60 changes: 60 additions & 0 deletions docs/databases/adbc.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,66 @@ with spec.provide_session(config) as session:
)
```

## PostgreSQL Connection Reuse

ADBC opens and closes a connection for each session by default. For short
PostgreSQL transactions, enable connection reuse with `pool_config={}` or supply
explicit bounds:

```python
import os

from sqlspec.adapters.adbc import AdbcConfig

config = AdbcConfig(
connection_config={"uri": os.environ["DATABASE_URI"]},
pool_config={"max_size": 4, "timeout": 30.0},
)
try:
with config.provide_session() as session:
value = session.select_value("SELECT :value", value=42)
session.commit()
finally:
config.close_pool()
```

`pool_config=None` keeps a fresh connection per session. An empty mapping gives
four leases and a 30-second wait limit. Each lease gives one caller sole use of a
connection. The pool holds one extra seed, for a total of `max_size + 1` native
connections. Nested sessions need separate leases and can time out when the pool
is full. Standalone connections do not count toward this limit.

Both native packages, `adbc-driver-manager` and `adbc-driver-postgresql`, must be
version 1.12.0 or newer. This pool supports only the native PostgreSQL driver
with `autocommit=False`. It rejects supplied connections and
`on_connection_create` hooks. Other backends keep a fresh connection per
session. The `supports_connection_pooling` flag means the adapter offers a
pool; the flag does not say whether a given config has enabled it.

On clean exit, the pool rolls back unfinished work, runs `DISCARD ALL` outside
a transaction, and turns native autocommit off. This clears committed session
settings, temporary tables, prepared statements, listeners, and advisory locks.
A failed session or reset drops that connection from reuse. Direct changes to
native connection options fall outside this reset contract. Measure complete
transactions, including reset, on your own workload before choosing a pool.

Lazy row streams and Arrow readers belong to their session. On exit, the
session closes their native readers and cursors, then drops the connection
from reuse. This also applies to streams that were never read or fully read.
Consume streams inside the session. Materialized tables and eagerly drained
batch lists stay valid afterward and allow reuse.

`close_pool()` blocks new checkouts and closes idle connections. Active leases
finish first, then close; their work is not interrupted. If native cleanup
fails, call `close_pool()` again to retry. The pool keeps ownership until every
handle is closed. A later explicit session can then start a new generation.
Create configs after forking: a pool from the parent process refuses use in a
child. Pools do not refresh credentials on their own.

`create_connection()` and `provide_connection()` remain separate from the pool.
An unpooled `connection_instance` stays open when a session ends; the caller
owns it.

## Key Driver Features and Pool Tuning

| Setting | Location | Description |
Expand Down
6 changes: 3 additions & 3 deletions docs/databases/arrow-odbc.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ config = spec.add_config(
},
statement_config=StatementConfig(dialect="tsql"),
driver_features={
"enable_driver_pooling": True,
"enable_pooling": True,
"chunk_size": 65536,
"fetch_concurrently": True,
},
Expand All @@ -60,13 +60,13 @@ config = spec.add_config(

## Key Driver Features and Pool Tuning

`ArrowOdbcConfig` subclasses `NoPoolSyncConfig` and delegates connection reuse to ODBC Driver Manager pooling when `enable_driver_pooling=True`:
`ArrowOdbcConfig` subclasses `NoPoolSyncConfig` and delegates connection reuse to ODBC Driver Manager pooling when `enable_pooling=True`:

| Setting | Location | Description |
| --- | --- | --- |
| `connection_string` | `connection_config` | Standard semicolon-delimited ODBC connection string (`Driver={...};Server=...;`). |
| `user` / `password` | `connection_config` | Optional credentials passed alongside the ODBC connection string. |
| `enable_driver_pooling` | `driver_features` | Enables process-wide ODBC Driver Manager connection pooling for low-latency session checkouts. |
| `enable_pooling` | `driver_features` | Enables process-wide ODBC Driver Manager connection pooling for low-latency session checkouts. |
| `chunk_size` / `max_bytes_per_batch` | `driver_features` | Maximum rows and memory bytes allocated per Arrow `RecordBatch` buffer during streaming reads. |
| `fetch_concurrently` | `driver_features` | Allocates double-buffered background ODBC fetch threads in Rust while Python processes the current Arrow batch. |
| `max_text_size` / `max_binary_size` | `driver_features` | Upper byte bounds for unbounded `VARCHAR(MAX)` / `NVARCHAR(MAX)` / `VARBINARY(MAX)` columns. |
Expand Down
Loading
Loading