Driver¶
The driver module provides base classes and mixins for database operations. It defines the foundation for both synchronous and asynchronous database drivers.
Overview¶
The driver system consists of:
Base Drivers - Abstract base classes for sync/async drivers
Mixins - Reusable functionality for query operations
Transaction Management - Context managers for transactions
Result Processing - Standard result handling
Connection Lifecycle - Connection pooling and cleanup
Base Driver Classes¶
Synchronous Driver¶
- class sqlspec.driver._sync.SyncDriverAdapterBase[source]¶
Bases:
CommonDriverAttributesMixin,SQLTranslatorMixin,StorageDriverMixinBase class for synchronous database drivers.
Base class for synchronous database drivers.
Abstract methods to implement:
execute()- Execute SQL and return resultsexecute_many()- Execute SQL for multiple parameter setsbegin_transaction()- Start a transactioncommit_transaction()- Commit a transactionrollback_transaction()- Rollback a transactionclose()- Close the connection
- abstract property data_dictionary: SyncDataDictionaryBase¶
Get the data dictionary for this driver.
- Returns:
Data dictionary instance for metadata queries
- dispatch_statement_execution(statement, connection)[source]¶
Central execution dispatcher using the Template Method Pattern.
- abstractmethod with_cursor(connection)[source]¶
Create and return a context manager for cursor acquisition and cleanup.
Returns a context manager that yields a cursor for database operations. Concrete implementations handle database-specific cursor creation and cleanup.
- Return type:
- abstractmethod handle_database_exceptions()[source]¶
Handle database-specific exceptions and wrap them appropriately.
- Return type:
- Returns:
ContextManager that can be used in with statements
- abstractmethod begin()[source]¶
Begin a database transaction on the current connection.
- Return type:
- abstractmethod rollback()[source]¶
Rollback the current transaction on the current connection.
- Return type:
- abstractmethod commit()[source]¶
Commit the current transaction on the current connection.
- Return type:
- execute_stack(stack, *, continue_on_error=False)[source]¶
Execute a StatementStack sequentially using the adapter’s primitives.
- Return type:
- execute(statement, /, *parameters, statement_config=None, **kwargs)[source]¶
Execute a statement with parameter handling.
- execute_many(statement, /, parameters, *filters, statement_config=None, **kwargs)[source]¶
Execute statement multiple times with different parameters.
Parameters passed will be used as the batch execution sequence.
- execute_script(statement, /, *parameters, statement_config=None, **kwargs)[source]¶
Execute a multi-statement script.
By default, validates each statement and logs warnings for dangerous operations. Use suppress_warnings=True for migrations and admin scripts.
- select_one(statement, /, *parameters, schema_type=None, statement_config=None, **kwargs)[source]¶
Execute a select statement and return exactly one row.
Raises an exception if no rows or more than one row is returned.
- select_one_or_none(statement, /, *parameters, schema_type=None, statement_config=None, **kwargs)[source]¶
Execute a select statement and return at most one row.
Returns None if no rows are found. Raises an exception if more than one row is returned.
- select(statement, /, *parameters, schema_type=None, statement_config=None, **kwargs)[source]¶
Execute a select statement and return all rows.
- select_to_arrow(statement, /, *parameters, statement_config=None, return_format='table', native_only=False, batch_size=None, arrow_schema=None, **kwargs)[source]¶
Execute query and return results as Apache Arrow format.
This base implementation uses the conversion path: execute() → dict → Arrow. Adapters with native Arrow support (ADBC, DuckDB, BigQuery) override this method to use zero-copy native paths for 5-10x performance improvement.
- Parameters:
statement¶ – SQL query string, Statement, or QueryBuilder
*parameters¶ – Query parameters (same format as execute()/select())
statement_config¶ – Optional statement configuration override
return_format¶ – “table” for pyarrow.Table (default), “batch” for single RecordBatch, “batches” for iterator of RecordBatches, “reader” for RecordBatchReader
native_only¶ – If True, raise error if native Arrow unavailable (default: False)
batch_size¶ – Rows per batch for “batch”/”batches” format (default: None = all rows)
arrow_schema¶ – Optional pyarrow.Schema for type casting
**kwargs¶ – Additional keyword arguments
- Returns:
ArrowResult containing pyarrow.Table, RecordBatchReader, or RecordBatches
- Raises:
ImproperConfigurationError – If native_only=True and adapter doesn’t support native Arrow
Examples
>>> result = driver.select_to_arrow( ... "SELECT * FROM users WHERE age > ?", 18 ... ) >>> df = result.to_pandas() >>> print(df.head())
>>> # Force native Arrow path (raises error if unavailable) >>> result = driver.select_to_arrow( ... "SELECT * FROM users", native_only=True ... )
- select_value(statement, /, *parameters, statement_config=None, **kwargs)[source]¶
Execute a select statement and return a single scalar value.
Expects exactly one row with one column. Raises an exception if no rows or more than one row/column is returned.
- select_value_or_none(statement, /, *parameters, statement_config=None, **kwargs)[source]¶
Execute a select statement and return a single scalar value or None.
Returns None if no rows are found. Expects at most one row with one column. Raises an exception if more than one row is returned.
- select_with_total(statement, /, *parameters, schema_type=None, statement_config=None, **kwargs)[source]¶
Execute a select statement and return both the data and total count.
This method is designed for pagination scenarios where you need both the current page of data and the total number of rows that match the query.
- Parameters:
- Returns:
List of data rows (transformed by schema_type if provided)
Total count of rows matching the query (ignoring LIMIT/OFFSET)
- Return type:
A tuple containing
Asynchronous Driver¶
- class sqlspec.driver._async.AsyncDriverAdapterBase[source]¶
Bases:
CommonDriverAttributesMixin,SQLTranslatorMixin,StorageDriverMixinBase class for asynchronous database drivers.
Base class for asynchronous database drivers.
Abstract methods to implement:
execute()- Execute SQL and return results (async)execute_many()- Execute SQL for multiple parameter sets (async)begin_transaction()- Start a transaction (async)commit_transaction()- Commit a transaction (async)rollback_transaction()- Rollback a transaction (async)close()- Close the connection (async)
- abstract property data_dictionary: AsyncDataDictionaryBase¶
Get the data dictionary for this driver.
- Returns:
Data dictionary instance for metadata queries
- async dispatch_statement_execution(statement, connection)[source]¶
Central execution dispatcher using the Template Method Pattern.
- abstractmethod with_cursor(connection)[source]¶
Create and return an async context manager for cursor acquisition and cleanup.
Returns an async context manager that yields a cursor for database operations. Concrete implementations handle database-specific cursor creation and cleanup.
- Return type:
- abstractmethod handle_database_exceptions()[source]¶
Handle database-specific exceptions and wrap them appropriately.
- Return type:
- Returns:
AsyncContextManager that can be used in async with statements
- abstractmethod async begin()[source]¶
Begin a database transaction on the current connection.
- Return type:
- abstractmethod async rollback()[source]¶
Rollback the current transaction on the current connection.
- Return type:
- abstractmethod async commit()[source]¶
Commit the current transaction on the current connection.
- Return type:
- async execute_stack(stack, *, continue_on_error=False)[source]¶
Execute a StatementStack sequentially using the adapter’s primitives.
- Return type:
- async execute(statement, /, *parameters, statement_config=None, **kwargs)[source]¶
Execute a statement with parameter handling.
- async execute_many(statement, /, parameters, *filters, statement_config=None, **kwargs)[source]¶
Execute statement multiple times with different parameters.
Parameters passed will be used as the batch execution sequence.
- async execute_script(statement, /, *parameters, statement_config=None, **kwargs)[source]¶
Execute a multi-statement script.
By default, validates each statement and logs warnings for dangerous operations. Use suppress_warnings=True for migrations and admin scripts.
- async select_one(statement, /, *parameters, schema_type=None, statement_config=None, **kwargs)[source]¶
Execute a select statement and return exactly one row.
Raises an exception if no rows or more than one row is returned.
- async select_one_or_none(statement, /, *parameters, schema_type=None, statement_config=None, **kwargs)[source]¶
Execute a select statement and return at most one row.
Returns None if no rows are found. Raises an exception if more than one row is returned.
- async select(statement, /, *parameters, schema_type=None, statement_config=None, **kwargs)[source]¶
Execute a select statement and return all rows.
- async select_to_arrow(statement, /, *parameters, statement_config=None, return_format='table', native_only=False, batch_size=None, arrow_schema=None, **kwargs)[source]¶
Execute query and return results as Apache Arrow format (async).
This base implementation uses the conversion path: execute() → dict → Arrow. Adapters with native Arrow support (ADBC, DuckDB, BigQuery) override this method to use zero-copy native paths for 5-10x performance improvement.
- Parameters:
statement¶ – SQL query string, Statement, or QueryBuilder
*parameters¶ – Query parameters (same format as execute()/select())
statement_config¶ – Optional statement configuration override
return_format¶ – “table” for pyarrow.Table (default), “batch” for single RecordBatch, “batches” for iterator of RecordBatches, “reader” for RecordBatchReader
native_only¶ – If True, raise error if native Arrow unavailable (default: False)
batch_size¶ – Rows per batch for “batch”/”batches” format (default: None = all rows)
arrow_schema¶ – Optional pyarrow.Schema for type casting
**kwargs¶ – Additional keyword arguments
- Returns:
ArrowResult containing pyarrow.Table, RecordBatchReader, or RecordBatches
- Raises:
ImproperConfigurationError – If native_only=True and adapter doesn’t support native Arrow
Examples
>>> result = await driver.select_to_arrow( ... "SELECT * FROM users WHERE age > ?", 18 ... ) >>> df = result.to_pandas() >>> print(df.head())
>>> # Force native Arrow path (raises error if unavailable) >>> result = await driver.select_to_arrow( ... "SELECT * FROM users", native_only=True ... )
- async select_value(statement, /, *parameters, statement_config=None, **kwargs)[source]¶
Execute a select statement and return a single scalar value.
Expects exactly one row with one column. Raises an exception if no rows or more than one row/column is returned.
- async select_value_or_none(statement, /, *parameters, statement_config=None, **kwargs)[source]¶
Execute a select statement and return a single scalar value or None.
Returns None if no rows are found. Expects at most one row with one column. Raises an exception if more than one row is returned.
- async select_with_total(statement, /, *parameters, schema_type=None, statement_config=None, **kwargs)[source]¶
Execute a select statement and return both the data and total count.
This method is designed for pagination scenarios where you need both the current page of data and the total number of rows that match the query.
- Parameters:
- Returns:
List of data rows (transformed by schema_type if provided)
Total count of rows matching the query (ignoring LIMIT/OFFSET)
- Return type:
A tuple containing
Driver Mixins¶
Transaction Management¶
Both sync and async drivers support transaction context managers:
# Async transactions
await driver.execute("INSERT INTO users VALUES (?, ?)", "Bob", 25)
await driver.execute("UPDATE accounts SET balance = balance - 50 WHERE user = ?", "Bob")
Connection Pooling¶
Common driver attributes and utilities.
- class sqlspec.driver._common.CommonDriverAttributesMixin[source]¶
Bases:
objectCommon attributes and methods for driver adapters.
- __init__(connection, statement_config, driver_features=None, observability=None)[source]¶
Initialize driver adapter with connection and configuration.
- Parameters:
connection¶ (typing.Any) – Database connection instance
statement_config¶ (
StatementConfig) – Statement configuration for the driverdriver_features¶ (
dict[str, typing.Any] |None) – Driver-specific features like extensions, secrets, and connection callbacksobservability¶ (
ObservabilityRuntime|None) – Optional runtime handling lifecycle hooks, observers, and spans
- connection: Any¶
- statement_config: StatementConfig¶
- driver_features: dict[str, Any]¶
- property observability: ObservabilityRuntime¶
Return the observability runtime, creating a disabled instance when absent.
- property stack_native_disabled: bool¶
Return True when native stack execution is disabled for this driver.
- create_execution_result(cursor_result, *, rowcount_override=None, special_data=None, selected_data=None, column_names=None, data_row_count=None, statement_count=None, successful_statements=None, is_script_result=False, is_select_result=False, is_many_result=False, last_inserted_id=None)[source]¶
Create ExecutionResult with all necessary data for any operation type.
- Parameters:
cursor_result¶ (
Any) – The raw result returned by the database cursor/driverrowcount_override¶ (
int|None) – Optional override for the number of affected rowsspecial_data¶ (
Any) – Any special metadata or additional informationselected_data¶ (
Optional[list[dict[str, typing.Any]]]) – For SELECT operations, the extracted row datacolumn_names¶ (
Optional[list[str]]) – For SELECT operations, the column namesdata_row_count¶ (
int|None) – For SELECT operations, the number of rows returnedstatement_count¶ (
int|None) – For script operations, total number of statementssuccessful_statements¶ (
int|None) – For script operations, number of successful statementsis_script_result¶ (
bool) – Whether this result is from script executionis_select_result¶ (
bool) – Whether this result is from a SELECT operationis_many_result¶ (
bool) – Whether this result is from an execute_many operationlast_inserted_id¶ (
int|str|None) – The ID of the last inserted row (if applicable)
- Return type:
- Returns:
ExecutionResult configured for the specified operation type
- build_statement_result(statement, execution_result)[source]¶
Build and return the SQLResult from ExecutionResult data.
- Parameters:
execution_result¶ (
ExecutionResult) – ExecutionResult containing all necessary data
- Return type:
- Returns:
SQLResult with complete execution data
- prepare_statement(statement, parameters=(), *, statement_config, kwargs=None)[source]¶
Build SQL statement from various input types.
Ensures dialect is set and preserves existing state when rebuilding SQL objects.
- split_script_statements(script, statement_config, strip_trailing_semicolon=False)[source]¶
Split a SQL script into individual statements.
Uses a lexer-driven state machine to handle multi-statement scripts, including complex constructs like PL/SQL blocks, T-SQL batches, and nested blocks.
- prepare_driver_parameters(parameters, statement_config, is_many=False, prepared_statement=None)[source]¶
Prepare parameters for database driver consumption.
Normalizes parameter structure and unwraps TypedParameter objects to their underlying values, which database drivers expect.
- Parameters:
parameters¶ (
Any) – Parameters in any format (dict, list, tuple, scalar, TypedParameter)statement_config¶ (
StatementConfig) – Statement configuration for parameter style detectionis_many¶ (
bool) – If True, handle as executemany parameter sequenceprepared_statement¶ (
Any|None) – Optional prepared statement containing metadata for parameter processing
- Return type:
- Returns:
Parameters with TypedParameter objects unwrapped to primitive values
- class sqlspec.driver._common.DataDictionaryMixin[source]¶
Bases:
objectMixin providing common data dictionary functionality.
- parse_version_string(version_str)[source]¶
Parse version string into VersionInfo.
- Parameters:
- Return type:
- Returns:
VersionInfo instance or None if parsing fails
- detect_version_with_queries(driver, queries)[source]¶
Try multiple version queries to detect database version.
- class sqlspec.driver._common.ExecutionResult[source]¶
Bases:
NamedTupleExecution result containing all data needed for SQLResult building.
- class sqlspec.driver._common.ScriptExecutionResult[source]¶
Bases:
NamedTupleResult from script execution with statement count information.
- class sqlspec.driver._common.StackExecutionObserver[source]¶
Bases:
objectContext manager that aggregates telemetry for stack execution.
- driver¶
- stack¶
- continue_on_error¶
- native_pipeline¶
- runtime¶
- metrics¶
- hashed_operations¶
- span: Any | None¶
- started¶
- class sqlspec.driver._common.VersionInfo[source]¶
Bases:
objectDatabase version information.
- sqlspec.driver._common.describe_stack_statement(statement)[source]¶
Return a readable representation of a stack statement for diagnostics.
- Return type:
- sqlspec.driver._common.handle_single_row_error(error)[source]¶
Normalize single-row selection errors to SQLSpec exceptions.
- Return type:
- sqlspec.driver._common.hash_stack_operations(stack)[source]¶
Return SHA256 fingerprints for statements contained in the stack.
- sqlspec.driver._common.make_cache_key_hashable(obj)[source]¶
Recursively convert unhashable types to hashable ones for cache keys.
For array-like objects (NumPy arrays, Python arrays, etc.), we use structural info (dtype + shape or typecode + length) rather than content for cache keys. This ensures high cache hit rates for parameterized queries with different vector values while avoiding expensive content hashing.
- Parameters:
- Return type:
- Returns:
A hashable representation of the object. Collections become tuples, arrays become structural tuples like (“ndarray”, dtype, shape).
Examples
>>> make_cache_key_hashable([1, 2, 3]) (1, 2, 3) >>> make_cache_key_hashable({"a": 1, "b": 2}) (('a', 1), ('b', 2))
Driver Protocols¶
See Also¶
Adapters - Database adapters built on driver system
Base - SQLSpec configuration
Core - Core SQL processing
Creating Adapters - Adapter creation guide