Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions docs/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,12 @@ v0.63.0 - Transactions, table fixtures, SQL fragments, storage, and kwargs param
the explicit ``native_json=True`` override remains available.
(`#781 <https://github.com/litestar-org/sqlspec/pull/781>`_)

* Expose :class:`~sqlspec.core.TypeCoercionCapabilities` on all adapter configuration classes
as a ``type_coercion_capabilities`` ClassVar, declaring each adapter's datetime binding mode
(``native``, ``iso_text``, or ``naive_utc``), timestamp precision (``microsecond``, ``millisecond``, or ``second``),
JSON column decoding behavior, and UUID binding mode (``native`` or ``text``).
(`#780 <https://github.com/litestar-org/sqlspec/issues/780>`_)

* Sync and async drivers provide :meth:`~sqlspec.driver.SyncDriverAdapterBase.transaction`, a context manager that begins a
transaction, commits when the block succeeds, and rolls back and re-raises when
it fails; a failed commit is followed by a rollback attempt. A block entered while
Expand Down Expand Up @@ -208,6 +214,9 @@ v0.63.0 - Transactions, table fixtures, SQL fragments, storage, and kwargs param

**Fixed:**

* Preserve JSON objects and arrays as individual query parameters after placeholder conversion,
instead of reinterpreting them as batches during parameter validation.

* SQLite and aiosqlite adapters map primary key constraint violations (extended error code 1555
and ``SQLITE_CONSTRAINT_PRIMARYKEY``) to ``UniqueViolationError``.
(`#775 <https://github.com/litestar-org/sqlspec/pull/775>`_)
Expand Down
86 changes: 86 additions & 0 deletions docs/reference/adapters/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,12 @@ the session when deciding whether to verify a modifying statement with a follow-
query. The flag describes affected-row reporting for individual DML statements;
SELECT, scripts, and batch operations retain their adapter-specific count semantics.

Type coercion capabilities describe the default adapter parameter and result paths.
Custom statement coercions, driver feature overrides, and database column types can
change these behaviors. Timestamp precision describes the adapter binding path; a
lower-precision database column can still truncate the value. ``native`` binding
means the parameter pipeline preserves the Python value for the driver.

.. list-table::
:header-rows: 1

Expand All @@ -139,139 +145,219 @@ SELECT, scripts, and batch operations retain their adapter-specific count semant
- Arrow Support
- Native Pipelines
- Reliable rowcount
- Datetime Binding
- Timestamp Precision
- JSON Decoded
- UUID Binding
* - asyncpg
-
- Yes
- Yes
- Yes
- Yes
- Yes
- Native
- Microsecond
- Yes
- Native
* - psycopg
- Yes
- Yes
- Yes
- Yes
- Yes
- Yes
- Native
- Microsecond
- Yes
- Native
* - psqlpy
-
- Yes
- Yes
- Yes
-
- Yes
- Native
- Microsecond
- Yes
- Native
* - sqlite
- Yes
-
- Yes
-
-
- Yes
- ISO Text
- Microsecond
-
- Text
* - aiosqlite
-
- Yes
- Yes
-
-
- Yes
- ISO Text
- Microsecond
-
- Text
* - duckdb
- Yes
-
- Yes
- Yes
-
- Yes
- ISO Text
- Microsecond
-
- Text
* - oracledb
- Yes
- Yes
- Yes
-
- Yes
- Yes
- Native
- Microsecond
- Yes
- Native
* - mysql-connector
- Yes
- Yes
- Yes
-
-
- Yes
- Native
- Microsecond
-
- Text
* - pymysql
- Yes
-
- Yes
-
-
- Yes
- Native
- Microsecond
-
- Text
* - asyncmy
-
- Yes
- Yes
-
-
- Yes
- Native
- Microsecond
-
- Text
* - aiomysql
-
- Yes
- Yes
-
-
- Yes
- Native
- Microsecond
-
- Text
* - bigquery
- Yes
-
-
- Yes
-
- Yes
- Native
- Microsecond
- Yes
- Text
* - spanner
- Yes
-
- Yes
-
-
- Yes
- Native
- Microsecond
- Yes
- Text
* - cockroach (asyncpg)
-
- Yes
- Yes
- Yes
- Yes
- Yes
- Native
- Microsecond
- Yes
- Native
* - cockroach (psycopg)
- Yes
- Yes
- Yes
- Yes
- Yes
- Yes
- Native
- Microsecond
- Yes
- Native
* - adbc
- Yes
-
-
- Yes
-
- No
- Native
- Microsecond
-
- Native
* - arrow_odbc
- Yes
-
-
- Yes
-
- No
- ISO Text
- Microsecond
-
- Text
* - mssql_python
- Yes
-
- Yes
- Yes
-
- Yes
- Native
- Microsecond
-
- Native
* - pymssql
- Yes
-
- Yes
-
-
- Yes
- Native
- Microsecond
-
- Text

.. toctree::
:hidden:
Expand Down
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,7 @@ exclude = [
include = [
"sqlspec/base.py", # SQLSpec registry/session manager
"sqlspec/core/**/*.py", # Core module
"sqlspec/core/capabilities.py", # Introspectable type coercion capabilities
"sqlspec/builder/**/*.py", # Builder module
"sqlspec/exceptions.py", # Exceptions module
"sqlspec/loader.py", # Loader module
Expand Down
4 changes: 4 additions & 0 deletions sqlspec/adapters/adbc/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
from sqlspec.adapters.adbc.driver import AdbcDriver, AdbcExceptionHandler
from sqlspec.config import ExtensionConfigs, NoPoolSyncConfig
from sqlspec.core import StatementConfig
from sqlspec.core.capabilities import TypeCoercionCapabilities
from sqlspec.driver._sync import SyncPoolConnectionContext, SyncPoolSessionFactory
from sqlspec.exceptions import ImproperConfigurationError
from sqlspec.extensions.events import EventRuntimeHints
Expand Down Expand Up @@ -196,6 +197,9 @@ class AdbcConfig(NoPoolSyncConfig[AdbcConnection, AdbcDriver]):
supports_native_parquet_import: "ClassVar[bool]" = True
supports_reliable_rowcount: ClassVar[bool] = False
storage_partition_strategies: "ClassVar[tuple[str, ...]]" = ("fixed", "rows_per_chunk")
type_coercion_capabilities: "ClassVar[TypeCoercionCapabilities]" = TypeCoercionCapabilities(
datetime_binding="native", timestamp_precision="microsecond", json_columns_decoded=False, uuid_binding="native"
)
_connection_context_class: "ClassVar[type[AdbcConnectionContext]]" = AdbcConnectionContext
_session_factory_class: "ClassVar[type[_AdbcSessionConnectionHandler]]" = _AdbcSessionConnectionHandler
_session_context_class: "ClassVar[type[AdbcSessionContext]]" = AdbcSessionContext
Expand Down
4 changes: 4 additions & 0 deletions sqlspec/adapters/aiomysql/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
from sqlspec.adapters.aiomysql.core import apply_driver_features, default_statement_config
from sqlspec.adapters.aiomysql.driver import AiomysqlDriver, AiomysqlExceptionHandler
from sqlspec.config import AsyncDatabaseConfig, ExtensionConfigs
from sqlspec.core import TypeCoercionCapabilities
from sqlspec.driver._async import AsyncPoolConnectionContext, AsyncPoolSessionFactory
from sqlspec.exceptions import ImproperConfigurationError
from sqlspec.extensions.events import EventRuntimeHints
Expand Down Expand Up @@ -212,6 +213,9 @@ class AiomysqlConfig(AsyncDatabaseConfig[AiomysqlConnection, "AiomysqlPool", Aio
supports_native_arrow_import: ClassVar[bool] = True
supports_native_parquet_import: ClassVar[bool] = True
supports_native_row_streaming: ClassVar[bool] = True
type_coercion_capabilities: ClassVar[TypeCoercionCapabilities] = TypeCoercionCapabilities(
datetime_binding="native", timestamp_precision="microsecond", json_columns_decoded=False, uuid_binding="text"
)
_connection_context_class: "ClassVar[type[AiomysqlConnectionContext]]" = AiomysqlConnectionContext
_session_factory_class: "ClassVar[type[_AiomysqlSessionFactory]]" = _AiomysqlSessionFactory
_session_context_class: "ClassVar[type[AiomysqlSessionContext]]" = AiomysqlSessionContext
Expand Down
4 changes: 4 additions & 0 deletions sqlspec/adapters/aiosqlite/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
)
from sqlspec.adapters.aiosqlite.type_converter import register_type_handlers
from sqlspec.config import AsyncDatabaseConfig, ExtensionConfigs
from sqlspec.core.capabilities import TypeCoercionCapabilities
from sqlspec.driver._async import AsyncPoolConnectionContext, AsyncPoolSessionFactory
from sqlspec.exceptions import ImproperConfigurationError
from sqlspec.utils.config_tools import normalize_connection_config
Expand Down Expand Up @@ -251,6 +252,9 @@ class AiosqliteConfig(AsyncDatabaseConfig["AiosqliteConnection", AiosqliteConnec
supports_native_parquet_export: "ClassVar[bool]" = True
supports_native_parquet_import: "ClassVar[bool]" = True
supports_native_row_streaming: "ClassVar[bool]" = True
type_coercion_capabilities: "ClassVar[TypeCoercionCapabilities]" = TypeCoercionCapabilities(
datetime_binding="iso_text", timestamp_precision="microsecond", json_columns_decoded=False, uuid_binding="text"
)
_connection_context_class: "ClassVar[type[AiosqliteConnectionContext]]" = AiosqliteConnectionContext
_session_factory_class: "ClassVar[type[_AiosqliteSessionFactory]]" = _AiosqliteSessionFactory
_session_context_class: "ClassVar[type[AiosqliteSessionContext]]" = AiosqliteSessionContext
Expand Down
4 changes: 4 additions & 0 deletions sqlspec/adapters/arrow_odbc/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
)
from sqlspec.adapters.arrow_odbc.driver import ArrowOdbcDriver
from sqlspec.config import ExtensionConfigs, NoPoolSyncConfig
from sqlspec.core.capabilities import TypeCoercionCapabilities
from sqlspec.driver._sync import SyncPoolConnectionContext, SyncPoolSessionFactory
from sqlspec.exceptions import ImproperConfigurationError
from sqlspec.extensions.events import EventRuntimeHints
Expand Down Expand Up @@ -138,6 +139,9 @@ class ArrowOdbcConfig(NoPoolSyncConfig[ArrowOdbcConnection, ArrowOdbcDriver]):
supports_native_parquet_export: "ClassVar[bool]" = False
supports_native_parquet_import: "ClassVar[bool]" = False
supports_reliable_rowcount: "ClassVar[bool]" = False
type_coercion_capabilities: "ClassVar[TypeCoercionCapabilities]" = TypeCoercionCapabilities(
datetime_binding="iso_text", timestamp_precision="microsecond", json_columns_decoded=False, uuid_binding="text"
)
_connection_context_class: "ClassVar[type[ArrowOdbcConnectionContext]]" = ArrowOdbcConnectionContext
_session_factory_class: "ClassVar[type[_ArrowOdbcSessionConnectionHandler]]" = _ArrowOdbcSessionConnectionHandler
_session_context_class: "ClassVar[type[ArrowOdbcSessionContext]]" = ArrowOdbcSessionContext
Expand Down
4 changes: 4 additions & 0 deletions sqlspec/adapters/asyncmy/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
from sqlspec.adapters.asyncmy.core import apply_driver_features, default_statement_config
from sqlspec.adapters.asyncmy.driver import AsyncmyDriver, AsyncmyExceptionHandler
from sqlspec.config import AsyncDatabaseConfig, ExtensionConfigs
from sqlspec.core import TypeCoercionCapabilities
from sqlspec.driver._async import AsyncPoolConnectionContext, AsyncPoolSessionFactory
from sqlspec.exceptions import ImproperConfigurationError
from sqlspec.extensions.events import EventRuntimeHints
Expand Down Expand Up @@ -248,6 +249,9 @@ class AsyncmyConfig(AsyncDatabaseConfig[AsyncmyConnection, "AsyncmyPool", Asyncm
supports_native_arrow_import: ClassVar[bool] = True
supports_native_parquet_import: ClassVar[bool] = True
supports_native_row_streaming: ClassVar[bool] = True
type_coercion_capabilities: ClassVar[TypeCoercionCapabilities] = TypeCoercionCapabilities(
datetime_binding="native", timestamp_precision="microsecond", json_columns_decoded=False, uuid_binding="text"
)
_connection_context_class: "ClassVar[type[AsyncmyConnectionContext]]" = AsyncmyConnectionContext
_session_factory_class: "ClassVar[type[_AsyncmySessionFactory]]" = _AsyncmySessionFactory
_session_context_class: "ClassVar[type[AsyncmySessionContext]]" = AsyncmySessionContext
Expand Down
4 changes: 4 additions & 0 deletions sqlspec/adapters/asyncpg/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
)
from sqlspec.adapters.asyncpg.driver import AsyncpgDriver, AsyncpgExceptionHandler
from sqlspec.config import AsyncDatabaseConfig, ExtensionConfigs
from sqlspec.core.capabilities import TypeCoercionCapabilities
from sqlspec.driver._async import AsyncPoolConnectionContext, AsyncPoolSessionFactory
from sqlspec.exceptions import ImproperConfigurationError, MissingDependencyError
from sqlspec.extensions.events import EventRuntimeHints
Expand Down Expand Up @@ -276,6 +277,9 @@ class AsyncpgConfig(AsyncDatabaseConfig[AsyncpgConnection, "Pool[Record]", Async
supports_native_parquet_export: "ClassVar[bool]" = True
supports_native_parquet_import: "ClassVar[bool]" = True
supports_native_row_streaming: "ClassVar[bool]" = True
type_coercion_capabilities: "ClassVar[TypeCoercionCapabilities]" = TypeCoercionCapabilities(
datetime_binding="native", timestamp_precision="microsecond", json_columns_decoded=True, uuid_binding="native"
)
_connection_context_class: "ClassVar[type[AsyncpgConnectionContext]]" = AsyncpgConnectionContext
_session_factory_class: "ClassVar[type[_AsyncpgSessionFactory]]" = _AsyncpgSessionFactory
_session_context_class: "ClassVar[type[AsyncpgSessionContext]]" = AsyncpgSessionContext
Expand Down
4 changes: 4 additions & 0 deletions sqlspec/adapters/bigquery/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from sqlspec.adapters.bigquery.core import apply_driver_features, default_statement_config
from sqlspec.adapters.bigquery.driver import BigQueryDriver, BigQueryExceptionHandler
from sqlspec.config import ExtensionConfigs, NoPoolSyncConfig
from sqlspec.core import TypeCoercionCapabilities
from sqlspec.driver._sync import SyncPoolConnectionContext, SyncPoolSessionFactory
from sqlspec.exceptions import ImproperConfigurationError
from sqlspec.extensions.events import EventRuntimeHints
Expand Down Expand Up @@ -178,6 +179,9 @@ class BigQueryConfig(NoPoolSyncConfig[BigQueryConnection, BigQueryDriver]):
supports_arrow_streaming: ClassVar[bool] = True
supports_native_row_streaming: ClassVar[bool] = True
supports_native_parquet_export: ClassVar[bool] = True
type_coercion_capabilities: ClassVar[TypeCoercionCapabilities] = TypeCoercionCapabilities(
datetime_binding="native", timestamp_precision="microsecond", json_columns_decoded=True, uuid_binding="text"
)
_connection_context_class: "ClassVar[type[BigQueryConnectionContext]]" = BigQueryConnectionContext
_session_factory_class: "ClassVar[type[_BigQuerySessionConnectionHandler]]" = _BigQuerySessionConnectionHandler
_session_context_class: "ClassVar[type[BigQuerySessionContext]]" = BigQuerySessionContext
Expand Down
Loading
Loading