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
4 changes: 2 additions & 2 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,13 @@ repos:
- id: mixed-line-ending
- id: trailing-whitespace
- repo: https://github.com/charliermarsh/ruff-pre-commit
rev: "v0.9.1"
rev: "v0.9.4"
hooks:
- id: ruff
args: ["--fix"]
- id: ruff-format
- repo: https://github.com/codespell-project/codespell
rev: v2.3.0
rev: v2.4.1
hooks:
- id: codespell
additional_dependencies:
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ This list is not final. If you have a driver you'd like to see added, please ope
| [`spanner`](https://googleapis.dev/python/spanner/latest/index.html) | Spanner | Sync | 🗓️ |
| [`sqlserver`](https://docs.microsoft.com/en-us/sql/connect/python/pyodbc/python-sql-driver-for-pyodbc?view=sql-server-ver16) | SQL Server | Sync | 🗓️ |
| [`mysql`](https://dev.mysql.com/doc/connector-python/en/connector-python-api-mysql-connector-python.html) | MySQL | Sync | 🗓️ |
| [`snowflake`](https://docs.snowflake.com) | MySQL | Sync | 🗓️ |
| [`snowflake`](https://docs.snowflake.com) | Snowflake | Sync | 🗓️ |

## Proposed Project Structure

Expand Down
2 changes: 1 addition & 1 deletion docs/PYPI_README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ This list is not final. If you have a driver you'd like to see added, please ope
| [`spanner`](https://googleapis.dev/python/spanner/latest/index.html) | Spanner | Sync | 🗓️ |
| [`sqlserver`](https://docs.microsoft.com/en-us/sql/connect/python/pyodbc/python-sql-driver-for-pyodbc?view=sql-server-ver16) | SQL Server | Sync | 🗓️ |
| [`mysql`](https://dev.mysql.com/doc/connector-python/en/connector-python-api-mysql-connector-python.html) | MySQL | Sync | 🗓️ |
| [`snowflake`](https://docs.snowflake.com) | MySQL | Sync | 🗓️ |
| [`snowflake`](https://docs.snowflake.com) | Snowflake | Sync | 🗓️ |

## Proposed Project Structure

Expand Down
2 changes: 1 addition & 1 deletion sqlspec/__metadata__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

from importlib.metadata import PackageNotFoundError, metadata, version

__all__ = ["__project__", "__version__"]
__all__ = ("__project__", "__version__")

try:
__version__ = version("sqlspec")
Expand Down
4 changes: 2 additions & 2 deletions sqlspec/adapters/adbc/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from dataclasses import dataclass
from typing import TYPE_CHECKING

from sqlspec.base import GenericDatabaseConfig, NoPoolConfig
from sqlspec.base import NoPoolSyncConfig
from sqlspec.typing import Empty, EmptyType

if TYPE_CHECKING:
Expand All @@ -17,7 +17,7 @@


@dataclass
class AdbcDatabaseConfig(NoPoolConfig["Connection"], GenericDatabaseConfig):
class AdbcDatabaseConfig(NoPoolSyncConfig["Connection"]):
"""Configuration for ADBC connections.

This class provides configuration options for ADBC database connections using the
Expand Down
29 changes: 11 additions & 18 deletions sqlspec/adapters/aiosqlite/config.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
from __future__ import annotations

from contextlib import asynccontextmanager
from dataclasses import dataclass
from dataclasses import dataclass, field
from typing import TYPE_CHECKING, Any

from sqlspec.base import GenericDatabaseConfig, NoPoolConfig
from sqlspec.base import NoPoolSyncConfig
from sqlspec.exceptions import ImproperConfigurationError
from sqlspec.typing import Empty, EmptyType, dataclass_to_dict

Expand All @@ -19,7 +19,7 @@


@dataclass
class AiosqliteConfig(NoPoolConfig["Connection"], GenericDatabaseConfig):
class AiosqliteConfig(NoPoolSyncConfig["Connection"]):
"""Configuration for Aiosqlite database connections.

This class provides configuration options for Aiosqlite database connections, wrapping all parameters
Expand All @@ -28,28 +28,21 @@ class AiosqliteConfig(NoPoolConfig["Connection"], GenericDatabaseConfig):
For details see: https://github.com/omnilib/aiosqlite/blob/main/aiosqlite/__init__.pyi
"""

database: str
database: str = field(default=":memory:")
"""The path to the database file to be opened. Pass ":memory:" to open a connection to a database that resides in RAM instead of on disk."""

timeout: float | EmptyType = Empty
timeout: float | EmptyType = field(default=Empty)
"""How many seconds the connection should wait before raising an OperationalError when a table is locked. If another thread or process has acquired a shared lock, a wait for the specified timeout occurs."""

detect_types: int | EmptyType = Empty
detect_types: int | EmptyType = field(default=Empty)
"""Control whether and how data types are detected. It can be 0 (default) or a combination of PARSE_DECLTYPES and PARSE_COLNAMES."""

isolation_level: Literal["DEFERRED", "IMMEDIATE", "EXCLUSIVE"] | None | EmptyType = Empty
isolation_level: Literal["DEFERRED", "IMMEDIATE", "EXCLUSIVE"] | None | EmptyType = field(default=Empty)
"""The isolation_level of the connection. This can be None for autocommit mode or one of "DEFERRED", "IMMEDIATE" or "EXCLUSIVE"."""

check_same_thread: bool | EmptyType = Empty
check_same_thread: bool | EmptyType = field(default=Empty)
"""If True (default), ProgrammingError is raised if the database connection is used by a thread other than the one that created it. If False, the connection may be shared across multiple threads."""

factory: type[SQLite3Connection] | EmptyType = Empty
factory: type[SQLite3Connection] | EmptyType = field(default=Empty)
"""A custom Connection class factory. If given, must be a callable that returns a Connection instance."""

cached_statements: int | EmptyType = Empty
cached_statements: int | EmptyType = field(default=Empty)
"""The number of statements that SQLite will cache for this connection. The default is 128."""

uri: bool | EmptyType = Empty
uri: bool | EmptyType = field(default=Empty)
"""If set to True, database is interpreted as a URI with supported options."""

@property
Expand Down
4 changes: 2 additions & 2 deletions sqlspec/adapters/asyncmy/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from asyncmy.connection import Connection
from asyncmy.pool import Pool

from sqlspec.base import DatabaseConfigProtocol, GenericDatabaseConfig, GenericPoolConfig
from sqlspec.base import AsyncDatabaseConfig, GenericPoolConfig
from sqlspec.exceptions import ImproperConfigurationError
from sqlspec.typing import Empty, EmptyType, dataclass_to_dict

Expand Down Expand Up @@ -106,7 +106,7 @@ def pool_config_dict(self) -> dict[str, Any]:


@dataclass
class AsyncMyConfig(DatabaseConfigProtocol[Connection, Pool], GenericDatabaseConfig):
class AsyncMyConfig(AsyncDatabaseConfig[Connection, Pool]):
"""Asyncmy Configuration."""

__is_async__ = True
Expand Down
12 changes: 4 additions & 8 deletions sqlspec/adapters/asyncpg/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from contextlib import asynccontextmanager
from dataclasses import dataclass
from typing import TYPE_CHECKING, TypeVar, Union
from typing import TYPE_CHECKING, Any, TypeVar, Union

from asyncpg import Record
from asyncpg import create_pool as asyncpg_create_pool
Expand All @@ -11,14 +11,13 @@
from typing_extensions import TypeAlias

from sqlspec._serialization import decode_json, encode_json
from sqlspec.base import DatabaseConfigProtocol, GenericDatabaseConfig, GenericPoolConfig
from sqlspec.base import AsyncDatabaseConfig, GenericPoolConfig
from sqlspec.exceptions import ImproperConfigurationError
from sqlspec.typing import Empty, EmptyType, dataclass_to_dict

if TYPE_CHECKING:
from asyncio import AbstractEventLoop
from asyncio import AbstractEventLoop # pyright: ignore[reportAttributeAccessIssue]
from collections.abc import AsyncGenerator, Awaitable, Callable, Coroutine
from typing import Any


__all__ = (
Expand Down Expand Up @@ -73,12 +72,9 @@ class AsyncPgPoolConfig(GenericPoolConfig):


@dataclass
class AsyncPgConfig(DatabaseConfigProtocol[PgConnection, Pool], GenericDatabaseConfig):
class AsyncPgConfig(AsyncDatabaseConfig[PgConnection, Pool]):
"""Asyncpg Configuration."""

__is_async__ = True
__supports_connection_pooling__ = True

pool_config: AsyncPgPoolConfig | None = None
"""Asyncpg Pool configuration"""
json_deserializer: Callable[[str], Any] = decode_json
Expand Down
4 changes: 2 additions & 2 deletions sqlspec/adapters/duckdb/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

from duckdb import DuckDBPyConnection

from sqlspec.base import GenericDatabaseConfig, NoPoolConfig
from sqlspec.base import NoPoolSyncConfig
from sqlspec.exceptions import ImproperConfigurationError
from sqlspec.typing import Empty, EmptyType, dataclass_to_dict

Expand Down Expand Up @@ -66,7 +66,7 @@ def from_dict(cls, name: str, config: dict[str, Any] | bool | None = None) -> Ex


@dataclass
class DuckDBConfig(NoPoolConfig[DuckDBPyConnection], GenericDatabaseConfig):
class DuckDBConfig(NoPoolSyncConfig[DuckDBPyConnection]):
"""Configuration for DuckDB database connections.

This class provides configuration options for DuckDB database connections, wrapping all parameters
Expand Down
21 changes: 14 additions & 7 deletions sqlspec/adapters/oracledb/config/_asyncio.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@
from dataclasses import dataclass
from typing import TYPE_CHECKING

from oracledb import create_pool_async as oracledb_create_pool
from oracledb import create_pool_async as oracledb_create_pool # pyright: ignore[reportUnknownVariableType]
from oracledb.connection import AsyncConnection
from oracledb.pool import AsyncConnectionPool

from sqlspec.adapters.oracledb.config._common import (
OracleGenericDatabaseConfig,
OracleGenericPoolConfig,
)
from sqlspec.base import AsyncDatabaseConfig
from sqlspec.exceptions import ImproperConfigurationError
from sqlspec.typing import dataclass_to_dict

Expand All @@ -31,11 +31,18 @@ class OracleAsyncPoolConfig(OracleGenericPoolConfig[AsyncConnection, AsyncConnec


@dataclass
class OracleAsyncDatabaseConfig(OracleGenericDatabaseConfig[AsyncConnection, AsyncConnectionPool]):
"""Async Oracle database Configuration."""
class OracleAsyncDatabaseConfig(AsyncDatabaseConfig[AsyncConnection, AsyncConnectionPool]):
"""Oracle Async database Configuration.

__is_async__ = True
__supports_connection_pooling__ = True
This class provides the base configuration for Oracle database connections, extending
the generic database configuration with Oracle-specific settings. It supports both
thin and thick modes of the python-oracledb driver.([1](https://python-oracledb.readthedocs.io/en/latest/index.html))

The configuration supports all standard Oracle connection parameters and can be used
with both synchronous and asynchronous connections. It includes support for features
like Oracle Wallet, external authentication, connection pooling, and advanced security
options.([2](https://python-oracledb.readthedocs.io/en/latest/user_guide/tuning.html))
"""

pool_config: OracleAsyncPoolConfig | None = None
"""Oracle Pool configuration"""
Expand Down Expand Up @@ -94,5 +101,5 @@ async def provide_connection(self, *args: Any, **kwargs: Any) -> AsyncGenerator[
A connection instance.
"""
db_pool = await self.provide_pool(*args, **kwargs)
async with db_pool.acquire() as connection:
async with db_pool.acquire() as connection: # pyright: ignore[reportUnknownMemberType]
yield connection
22 changes: 2 additions & 20 deletions sqlspec/adapters/oracledb/config/_common.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

from oracledb import ConnectionPool

from sqlspec.base import DatabaseConfigProtocol, GenericDatabaseConfig, GenericPoolConfig
from sqlspec.base import GenericPoolConfig
from sqlspec.typing import Empty

if TYPE_CHECKING:
Expand All @@ -19,10 +19,7 @@

from sqlspec.typing import EmptyType

__all__ = (
"OracleGenericDatabaseConfig",
"OracleGenericPoolConfig",
)
__all__ = ("OracleGenericPoolConfig",)


T = TypeVar("T")
Expand Down Expand Up @@ -134,18 +131,3 @@ class OracleGenericPoolConfig(Generic[ConnectionT, PoolT], GenericPoolConfig):
"""SSL/TLS protocol version"""
handle: int | EmptyType = Empty
"""Oracle service context handle"""


@dataclass
class OracleGenericDatabaseConfig(DatabaseConfigProtocol[ConnectionT, PoolT], GenericDatabaseConfig):
"""Oracle database Configuration.

This class provides the base configuration for Oracle database connections, extending
the generic database configuration with Oracle-specific settings. It supports both
thin and thick modes of the python-oracledb driver.([1](https://python-oracledb.readthedocs.io/en/latest/index.html))

The configuration supports all standard Oracle connection parameters and can be used
with both synchronous and asynchronous connections. It includes support for features
like Oracle Wallet, external authentication, connection pooling, and advanced security
options.([2](https://python-oracledb.readthedocs.io/en/latest/user_guide/tuning.html))
"""
19 changes: 13 additions & 6 deletions sqlspec/adapters/oracledb/config/_sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@
from dataclasses import dataclass
from typing import TYPE_CHECKING

from oracledb import create_pool as oracledb_create_pool
from oracledb import create_pool as oracledb_create_pool # pyright: ignore[reportUnknownVariableType]
from oracledb.connection import Connection
from oracledb.pool import ConnectionPool

from sqlspec.adapters.oracledb.config._common import (
OracleGenericDatabaseConfig,
OracleGenericPoolConfig,
)
from sqlspec.base import SyncDatabaseConfig
from sqlspec.exceptions import ImproperConfigurationError
from sqlspec.typing import dataclass_to_dict

Expand All @@ -31,11 +31,18 @@ class OracleSyncPoolConfig(OracleGenericPoolConfig[Connection, ConnectionPool]):


@dataclass
class OracleSyncDatabaseConfig(OracleGenericDatabaseConfig[Connection, ConnectionPool]):
"""Oracle database Configuration."""
class OracleSyncDatabaseConfig(SyncDatabaseConfig[Connection, ConnectionPool]):
"""Oracle Sync database Configuration.

__is_async__ = False
__supports_connection_pooling__ = True
This class provides the base configuration for Oracle database connections, extending
the generic database configuration with Oracle-specific settings. It supports both
thin and thick modes of the python-oracledb driver.([1](https://python-oracledb.readthedocs.io/en/latest/index.html))

The configuration supports all standard Oracle connection parameters and can be used
with both synchronous and asynchronous connections. It includes support for features
like Oracle Wallet, external authentication, connection pooling, and advanced security
options.([2](https://python-oracledb.readthedocs.io/en/latest/user_guide/tuning.html))
"""

pool_config: OracleSyncPoolConfig | None = None
"""Oracle Pool configuration"""
Expand Down
18 changes: 10 additions & 8 deletions sqlspec/adapters/psycopg/config/_async.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,8 @@
from psycopg import AsyncConnection
from psycopg_pool import AsyncConnectionPool

from sqlspec.adapters.psycopg.config._common import (
PsycoPgGenericDatabaseConfig,
PsycoPgGenericPoolConfig,
)
from sqlspec.adapters.psycopg.config._common import PsycoPgGenericPoolConfig
from sqlspec.base import AsyncDatabaseConfig
from sqlspec.exceptions import ImproperConfigurationError
from sqlspec.typing import dataclass_to_dict

Expand All @@ -31,11 +29,15 @@ class PsycoPgAsyncPoolConfig(PsycoPgGenericPoolConfig[AsyncConnection, AsyncConn


@dataclass
class PsycoPgAsyncDatabaseConfig(PsycoPgGenericDatabaseConfig[AsyncConnection, AsyncConnectionPool]):
"""Async Psycopg database Configuration."""
class PsycoPgAsyncDatabaseConfig(AsyncDatabaseConfig[AsyncConnection, AsyncConnectionPool]):
"""Async Psycopg database Configuration.

This class provides the base configuration for Psycopg database connections, extending
the generic database configuration with Psycopg-specific settings.([1](https://www.psycopg.org/psycopg3/docs/api/connections.html))

__is_async__ = True
__supports_connection_pooling__ = True
The configuration supports all standard Psycopg connection parameters and can be used
with both synchronous and asynchronous connections.([2](https://www.psycopg.org/psycopg3/docs/api/connections.html))
"""

pool_config: PsycoPgAsyncPoolConfig | None = None
"""Psycopg Pool configuration"""
Expand Down
19 changes: 2 additions & 17 deletions sqlspec/adapters/psycopg/config/_common.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from dataclasses import dataclass
from typing import TYPE_CHECKING, Generic, TypeVar

from sqlspec.base import DatabaseConfigProtocol, GenericDatabaseConfig, GenericPoolConfig
from sqlspec.base import GenericPoolConfig
from sqlspec.typing import Empty

if TYPE_CHECKING:
Expand All @@ -16,10 +16,7 @@
from sqlspec.typing import EmptyType


__all__ = (
"PsycoPgGenericDatabaseConfig",
"PsycoPgGenericPoolConfig",
)
__all__ = ("PsycoPgGenericPoolConfig",)


ConnectionT = TypeVar("ConnectionT", bound="Connection | AsyncConnection")
Expand Down Expand Up @@ -59,15 +56,3 @@ class PsycoPgGenericPoolConfig(Generic[ConnectionT, PoolT], GenericPoolConfig):
"""Number of background workers"""
configure: Callable[[ConnectionT], None] | EmptyType = Empty
"""Callback to configure new connections"""


@dataclass
class PsycoPgGenericDatabaseConfig(DatabaseConfigProtocol[ConnectionT, PoolT], GenericDatabaseConfig):
"""Psycopg database Configuration.

This class provides the base configuration for Psycopg database connections, extending
the generic database configuration with Psycopg-specific settings.([1](https://www.psycopg.org/psycopg3/docs/api/connections.html))

The configuration supports all standard Psycopg connection parameters and can be used
with both synchronous and asynchronous connections.([2](https://www.psycopg.org/psycopg3/docs/api/connections.html))
"""
Loading