Source code for sqlspec.adapters.psycopg.config

"""Psycopg database configuration with direct field-based configuration."""

from typing import TYPE_CHECKING, Any, ClassVar, Literal, TypedDict, cast

from mypy_extensions import mypyc_attr
from psycopg import Connection as PsycopgConnection
from psycopg_pool import AsyncConnectionPool, ConnectionPool
from typing_extensions import NotRequired, Self

from sqlspec.adapters.psycopg._typing import (
    PsycopgAsyncConnection,
    PsycopgAsyncCursor,
    PsycopgAsyncSessionContext,
    PsycopgSyncConnection,
    PsycopgSyncCursor,
    PsycopgSyncSessionContext,
)
from sqlspec.adapters.psycopg.core import (
    apply_driver_features,
    build_postgres_extension_probe_names,
    default_statement_config,
    resolve_postgres_extension_state,
    resolve_runtime_statement_config,
)
from sqlspec.adapters.psycopg.driver import (
    PsycopgAsyncDriver,
    PsycopgAsyncExceptionHandler,
    PsycopgSyncDriver,
    PsycopgSyncExceptionHandler,
)
from sqlspec.adapters.psycopg.type_converter import register_pgvector_async, register_pgvector_sync
from sqlspec.config import AsyncDatabaseConfig, ExtensionConfigs, SyncDatabaseConfig
from sqlspec.driver._async import AsyncPoolConnectionContext, AsyncPoolSessionFactory
from sqlspec.driver._sync import SyncPoolConnectionContext, SyncPoolSessionFactory
from sqlspec.exceptions import ImproperConfigurationError, MissingDependencyError
from sqlspec.extensions.events import EventRuntimeHints
from sqlspec.typing import ALLOYDB_CONNECTOR_INSTALLED
from sqlspec.utils.config_tools import normalize_connection_config

if TYPE_CHECKING:
    from collections.abc import Awaitable, Callable
    from types import TracebackType

    from psycopg import AsyncConnection, AsyncCursor, Connection, Cursor
    from psycopg.abc import AdaptContext
    from psycopg.rows import AsyncRowFactory, RowFactory
    from psycopg_pool.abc import AsyncConnectFailedCB, AsyncConnectionCB, ConnectFailedCB, ConnectionCB

    from sqlspec.core import StatementConfig

__all__ = (
    "PsycopgAsyncConfig",
    "PsycopgAsyncCursor",
    "PsycopgConnectionParams",
    "PsycopgDriverFeatures",
    "PsycopgPoolParams",
    "PsycopgSyncConfig",
    "PsycopgSyncCursor",
)


PsycopgSSLMode = Literal["disable", "allow", "prefer", "require", "verify-ca", "verify-full"]
_ALLOYDB_DIRECT_CONNECTION_KEYS = ("conninfo", "host", "hostaddr", "port", "user", "password", "dbname", "db")
_ALLOYDB_CONNECTOR_PACKAGE = "google-cloud-alloydb-connector"


class PsycopgConnectionParams(TypedDict):
    """Psycopg connection parameters."""

    conninfo: NotRequired[str]
    host: NotRequired[str]
    port: NotRequired[int]
    user: NotRequired[str]
    password: NotRequired[str]
    dbname: NotRequired[str]
    connect_timeout: NotRequired[int]
    options: NotRequired[str]
    application_name: NotRequired[str]
    sslmode: NotRequired[PsycopgSSLMode]
    sslcert: NotRequired[str]
    sslkey: NotRequired[str]
    sslrootcert: NotRequired[str]
    autocommit: NotRequired[bool]
    prepare_threshold: NotRequired[int | None]
    context: NotRequired["AdaptContext | None"]
    row_factory: NotRequired["RowFactory[Any] | AsyncRowFactory[Any] | None"]
    cursor_factory: NotRequired["type[Cursor[Any] | AsyncCursor[Any]] | None"]
    extra: NotRequired["dict[str, Any]"]
class PsycopgPoolParams(PsycopgConnectionParams): """Psycopg pool parameters.""" min_size: NotRequired[int] max_size: NotRequired[int] connection_class: NotRequired["type[Connection[Any] | AsyncConnection[Any]]"] name: NotRequired[str] timeout: NotRequired[float] max_waiting: NotRequired[int] max_lifetime: NotRequired[float] max_idle: NotRequired[float] reconnect_timeout: NotRequired[float] num_workers: NotRequired[int] open: NotRequired[bool | None] configure: NotRequired["ConnectionCB[PsycopgSyncConnection] | AsyncConnectionCB[PsycopgAsyncConnection] | None"] check: NotRequired["ConnectionCB[PsycopgSyncConnection] | AsyncConnectionCB[PsycopgAsyncConnection] | None"] reset: NotRequired["ConnectionCB[PsycopgSyncConnection] | AsyncConnectionCB[PsycopgAsyncConnection] | None"] close_returns: NotRequired[bool] reconnect_failed: NotRequired["ConnectFailedCB | AsyncConnectFailedCB | None"] kwargs: NotRequired["dict[str, Any]"]