sqlspec 0.11.1__py3-none-any.whl → 0.12.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of sqlspec might be problematic. Click here for more details.

Files changed (155) hide show
  1. sqlspec/__init__.py +16 -3
  2. sqlspec/_serialization.py +3 -10
  3. sqlspec/_sql.py +1147 -0
  4. sqlspec/_typing.py +343 -41
  5. sqlspec/adapters/adbc/__init__.py +2 -6
  6. sqlspec/adapters/adbc/config.py +474 -149
  7. sqlspec/adapters/adbc/driver.py +330 -621
  8. sqlspec/adapters/aiosqlite/__init__.py +2 -6
  9. sqlspec/adapters/aiosqlite/config.py +143 -57
  10. sqlspec/adapters/aiosqlite/driver.py +269 -431
  11. sqlspec/adapters/asyncmy/__init__.py +3 -8
  12. sqlspec/adapters/asyncmy/config.py +247 -202
  13. sqlspec/adapters/asyncmy/driver.py +218 -436
  14. sqlspec/adapters/asyncpg/__init__.py +4 -7
  15. sqlspec/adapters/asyncpg/config.py +329 -176
  16. sqlspec/adapters/asyncpg/driver.py +417 -487
  17. sqlspec/adapters/bigquery/__init__.py +2 -2
  18. sqlspec/adapters/bigquery/config.py +407 -0
  19. sqlspec/adapters/bigquery/driver.py +600 -553
  20. sqlspec/adapters/duckdb/__init__.py +4 -1
  21. sqlspec/adapters/duckdb/config.py +432 -321
  22. sqlspec/adapters/duckdb/driver.py +392 -406
  23. sqlspec/adapters/oracledb/__init__.py +3 -8
  24. sqlspec/adapters/oracledb/config.py +625 -0
  25. sqlspec/adapters/oracledb/driver.py +548 -921
  26. sqlspec/adapters/psqlpy/__init__.py +4 -7
  27. sqlspec/adapters/psqlpy/config.py +372 -203
  28. sqlspec/adapters/psqlpy/driver.py +197 -533
  29. sqlspec/adapters/psycopg/__init__.py +3 -8
  30. sqlspec/adapters/psycopg/config.py +725 -0
  31. sqlspec/adapters/psycopg/driver.py +734 -694
  32. sqlspec/adapters/sqlite/__init__.py +2 -6
  33. sqlspec/adapters/sqlite/config.py +146 -81
  34. sqlspec/adapters/sqlite/driver.py +242 -405
  35. sqlspec/base.py +220 -784
  36. sqlspec/config.py +354 -0
  37. sqlspec/driver/__init__.py +22 -0
  38. sqlspec/driver/_async.py +252 -0
  39. sqlspec/driver/_common.py +338 -0
  40. sqlspec/driver/_sync.py +261 -0
  41. sqlspec/driver/mixins/__init__.py +17 -0
  42. sqlspec/driver/mixins/_pipeline.py +523 -0
  43. sqlspec/driver/mixins/_result_utils.py +122 -0
  44. sqlspec/driver/mixins/_sql_translator.py +35 -0
  45. sqlspec/driver/mixins/_storage.py +993 -0
  46. sqlspec/driver/mixins/_type_coercion.py +131 -0
  47. sqlspec/exceptions.py +299 -7
  48. sqlspec/extensions/aiosql/__init__.py +10 -0
  49. sqlspec/extensions/aiosql/adapter.py +474 -0
  50. sqlspec/extensions/litestar/__init__.py +1 -6
  51. sqlspec/extensions/litestar/_utils.py +1 -5
  52. sqlspec/extensions/litestar/config.py +5 -6
  53. sqlspec/extensions/litestar/handlers.py +13 -12
  54. sqlspec/extensions/litestar/plugin.py +22 -24
  55. sqlspec/extensions/litestar/providers.py +37 -55
  56. sqlspec/loader.py +528 -0
  57. sqlspec/service/__init__.py +3 -0
  58. sqlspec/service/base.py +24 -0
  59. sqlspec/service/pagination.py +26 -0
  60. sqlspec/statement/__init__.py +21 -0
  61. sqlspec/statement/builder/__init__.py +54 -0
  62. sqlspec/statement/builder/_ddl_utils.py +119 -0
  63. sqlspec/statement/builder/_parsing_utils.py +135 -0
  64. sqlspec/statement/builder/base.py +328 -0
  65. sqlspec/statement/builder/ddl.py +1379 -0
  66. sqlspec/statement/builder/delete.py +80 -0
  67. sqlspec/statement/builder/insert.py +274 -0
  68. sqlspec/statement/builder/merge.py +95 -0
  69. sqlspec/statement/builder/mixins/__init__.py +65 -0
  70. sqlspec/statement/builder/mixins/_aggregate_functions.py +151 -0
  71. sqlspec/statement/builder/mixins/_case_builder.py +91 -0
  72. sqlspec/statement/builder/mixins/_common_table_expr.py +91 -0
  73. sqlspec/statement/builder/mixins/_delete_from.py +34 -0
  74. sqlspec/statement/builder/mixins/_from.py +61 -0
  75. sqlspec/statement/builder/mixins/_group_by.py +119 -0
  76. sqlspec/statement/builder/mixins/_having.py +35 -0
  77. sqlspec/statement/builder/mixins/_insert_from_select.py +48 -0
  78. sqlspec/statement/builder/mixins/_insert_into.py +36 -0
  79. sqlspec/statement/builder/mixins/_insert_values.py +69 -0
  80. sqlspec/statement/builder/mixins/_join.py +110 -0
  81. sqlspec/statement/builder/mixins/_limit_offset.py +53 -0
  82. sqlspec/statement/builder/mixins/_merge_clauses.py +405 -0
  83. sqlspec/statement/builder/mixins/_order_by.py +46 -0
  84. sqlspec/statement/builder/mixins/_pivot.py +82 -0
  85. sqlspec/statement/builder/mixins/_returning.py +37 -0
  86. sqlspec/statement/builder/mixins/_select_columns.py +60 -0
  87. sqlspec/statement/builder/mixins/_set_ops.py +122 -0
  88. sqlspec/statement/builder/mixins/_unpivot.py +80 -0
  89. sqlspec/statement/builder/mixins/_update_from.py +54 -0
  90. sqlspec/statement/builder/mixins/_update_set.py +91 -0
  91. sqlspec/statement/builder/mixins/_update_table.py +29 -0
  92. sqlspec/statement/builder/mixins/_where.py +374 -0
  93. sqlspec/statement/builder/mixins/_window_functions.py +86 -0
  94. sqlspec/statement/builder/protocols.py +20 -0
  95. sqlspec/statement/builder/select.py +206 -0
  96. sqlspec/statement/builder/update.py +178 -0
  97. sqlspec/statement/filters.py +571 -0
  98. sqlspec/statement/parameters.py +736 -0
  99. sqlspec/statement/pipelines/__init__.py +67 -0
  100. sqlspec/statement/pipelines/analyzers/__init__.py +9 -0
  101. sqlspec/statement/pipelines/analyzers/_analyzer.py +649 -0
  102. sqlspec/statement/pipelines/base.py +315 -0
  103. sqlspec/statement/pipelines/context.py +119 -0
  104. sqlspec/statement/pipelines/result_types.py +41 -0
  105. sqlspec/statement/pipelines/transformers/__init__.py +8 -0
  106. sqlspec/statement/pipelines/transformers/_expression_simplifier.py +256 -0
  107. sqlspec/statement/pipelines/transformers/_literal_parameterizer.py +623 -0
  108. sqlspec/statement/pipelines/transformers/_remove_comments.py +66 -0
  109. sqlspec/statement/pipelines/transformers/_remove_hints.py +81 -0
  110. sqlspec/statement/pipelines/validators/__init__.py +23 -0
  111. sqlspec/statement/pipelines/validators/_dml_safety.py +275 -0
  112. sqlspec/statement/pipelines/validators/_parameter_style.py +297 -0
  113. sqlspec/statement/pipelines/validators/_performance.py +703 -0
  114. sqlspec/statement/pipelines/validators/_security.py +990 -0
  115. sqlspec/statement/pipelines/validators/base.py +67 -0
  116. sqlspec/statement/result.py +527 -0
  117. sqlspec/statement/splitter.py +701 -0
  118. sqlspec/statement/sql.py +1198 -0
  119. sqlspec/storage/__init__.py +15 -0
  120. sqlspec/storage/backends/__init__.py +0 -0
  121. sqlspec/storage/backends/base.py +166 -0
  122. sqlspec/storage/backends/fsspec.py +315 -0
  123. sqlspec/storage/backends/obstore.py +464 -0
  124. sqlspec/storage/protocol.py +170 -0
  125. sqlspec/storage/registry.py +315 -0
  126. sqlspec/typing.py +157 -36
  127. sqlspec/utils/correlation.py +155 -0
  128. sqlspec/utils/deprecation.py +3 -6
  129. sqlspec/utils/fixtures.py +6 -11
  130. sqlspec/utils/logging.py +135 -0
  131. sqlspec/utils/module_loader.py +45 -43
  132. sqlspec/utils/serializers.py +4 -0
  133. sqlspec/utils/singleton.py +6 -8
  134. sqlspec/utils/sync_tools.py +15 -27
  135. sqlspec/utils/text.py +58 -26
  136. {sqlspec-0.11.1.dist-info → sqlspec-0.12.1.dist-info}/METADATA +97 -26
  137. sqlspec-0.12.1.dist-info/RECORD +145 -0
  138. sqlspec/adapters/bigquery/config/__init__.py +0 -3
  139. sqlspec/adapters/bigquery/config/_common.py +0 -40
  140. sqlspec/adapters/bigquery/config/_sync.py +0 -87
  141. sqlspec/adapters/oracledb/config/__init__.py +0 -9
  142. sqlspec/adapters/oracledb/config/_asyncio.py +0 -186
  143. sqlspec/adapters/oracledb/config/_common.py +0 -131
  144. sqlspec/adapters/oracledb/config/_sync.py +0 -186
  145. sqlspec/adapters/psycopg/config/__init__.py +0 -19
  146. sqlspec/adapters/psycopg/config/_async.py +0 -169
  147. sqlspec/adapters/psycopg/config/_common.py +0 -56
  148. sqlspec/adapters/psycopg/config/_sync.py +0 -168
  149. sqlspec/filters.py +0 -331
  150. sqlspec/mixins.py +0 -305
  151. sqlspec/statement.py +0 -378
  152. sqlspec-0.11.1.dist-info/RECORD +0 -69
  153. {sqlspec-0.11.1.dist-info → sqlspec-0.12.1.dist-info}/WHEEL +0 -0
  154. {sqlspec-0.11.1.dist-info → sqlspec-0.12.1.dist-info}/licenses/LICENSE +0 -0
  155. {sqlspec-0.11.1.dist-info → sqlspec-0.12.1.dist-info}/licenses/NOTICE +0 -0
@@ -1,169 +0,0 @@
1
- from contextlib import asynccontextmanager
2
- from dataclasses import dataclass, field
3
- from typing import TYPE_CHECKING, Any, Optional
4
-
5
- from psycopg_pool import AsyncConnectionPool
6
-
7
- from sqlspec.adapters.psycopg.config._common import PsycopgGenericPoolConfig
8
- from sqlspec.adapters.psycopg.driver import PsycopgAsyncConnection, PsycopgAsyncDriver
9
- from sqlspec.base import AsyncDatabaseConfig
10
- from sqlspec.exceptions import ImproperConfigurationError
11
- from sqlspec.typing import dataclass_to_dict
12
-
13
- if TYPE_CHECKING:
14
- from collections.abc import AsyncGenerator, Awaitable
15
-
16
-
17
- __all__ = (
18
- "PsycopgAsyncConfig",
19
- "PsycopgAsyncPoolConfig",
20
- )
21
-
22
-
23
- @dataclass
24
- class PsycopgAsyncPoolConfig(PsycopgGenericPoolConfig[PsycopgAsyncConnection, AsyncConnectionPool]):
25
- """Async Psycopg Pool Config"""
26
-
27
-
28
- @dataclass
29
- class PsycopgAsyncConfig(AsyncDatabaseConfig[PsycopgAsyncConnection, AsyncConnectionPool, PsycopgAsyncDriver]):
30
- """Async Psycopg database Configuration.
31
-
32
- This class provides the base configuration for Psycopg database connections, extending
33
- the generic database configuration with Psycopg-specific settings.([1](https://www.psycopg.org/psycopg3/docs/api/connections.html))
34
-
35
- The configuration supports all standard Psycopg connection parameters and can be used
36
- with both synchronous and asynchronous connections.([2](https://www.psycopg.org/psycopg3/docs/api/connections.html))
37
- """
38
-
39
- pool_config: "Optional[PsycopgAsyncPoolConfig]" = None
40
- """Psycopg Pool configuration"""
41
- pool_instance: "Optional[AsyncConnectionPool]" = None
42
- """Optional pool to use"""
43
- connection_type: "type[PsycopgAsyncConnection]" = field(init=False, default_factory=lambda: PsycopgAsyncConnection) # type: ignore[assignment]
44
- """Type of the connection object"""
45
- driver_type: "type[PsycopgAsyncDriver]" = field(init=False, default_factory=lambda: PsycopgAsyncDriver) # type: ignore[type-abstract,unused-ignore]
46
- """Type of the driver object"""
47
-
48
- @property
49
- def connection_config_dict(self) -> "dict[str, Any]":
50
- """Return the connection configuration as a dict.
51
-
52
- Returns:
53
- A string keyed dict of config kwargs for the psycopg.connect function.
54
-
55
- Raises:
56
- ImproperConfigurationError: If the connection configuration is not provided.
57
- """
58
- if self.pool_config:
59
- # Filter out pool-specific parameters
60
- pool_only_params = {
61
- "min_size",
62
- "max_size",
63
- "name",
64
- "timeout",
65
- "reconnect_timeout",
66
- "max_idle",
67
- "max_lifetime",
68
- }
69
- return dataclass_to_dict(
70
- self.pool_config,
71
- exclude_empty=True,
72
- convert_nested=False,
73
- exclude=pool_only_params.union({"pool_instance", "connection_type", "driver_type", "open"}),
74
- )
75
- msg = "You must provide a 'pool_config' for this adapter."
76
- raise ImproperConfigurationError(msg)
77
-
78
- @property
79
- def pool_config_dict(self) -> "dict[str, Any]":
80
- """Return the pool configuration as a dict.
81
-
82
- Raises:
83
- ImproperConfigurationError: If pool_config is not set but pool_instance is provided.
84
- """
85
- if self.pool_config:
86
- return dataclass_to_dict(
87
- self.pool_config,
88
- exclude_empty=True,
89
- convert_nested=False,
90
- exclude={"pool_instance", "connection_type", "driver_type"},
91
- )
92
- msg = "'pool_config' methods can not be used when a 'pool_instance' is provided."
93
- raise ImproperConfigurationError(msg)
94
-
95
- async def create_connection(self) -> "PsycopgAsyncConnection":
96
- """Create and return a new psycopg async connection from the pool.
97
-
98
- Returns:
99
- An AsyncConnection instance.
100
-
101
- Raises:
102
- ImproperConfigurationError: If the connection could not be created.
103
- """
104
- try:
105
- pool = await self.provide_pool()
106
- return await pool.getconn()
107
- except Exception as e:
108
- msg = f"Could not configure the Psycopg connection. Error: {e!s}"
109
- raise ImproperConfigurationError(msg) from e
110
-
111
- async def create_pool(self) -> "AsyncConnectionPool":
112
- """Create and return a connection pool.
113
-
114
- Returns:
115
- AsyncConnectionPool: The configured connection pool.
116
-
117
- Raises:
118
- ImproperConfigurationError: If neither pool_config nor pool_instance are provided
119
- or if pool creation fails.
120
- """
121
- if self.pool_instance is not None:
122
- return self.pool_instance
123
-
124
- if self.pool_config is None:
125
- msg = "One of 'pool_config' or 'pool_instance' must be provided."
126
- raise ImproperConfigurationError(msg)
127
-
128
- pool_config = self.pool_config_dict
129
- self.pool_instance = AsyncConnectionPool(open=False, **pool_config)
130
- if self.pool_instance is None: # pyright: ignore[reportUnnecessaryComparison]
131
- msg = "Could not configure the 'pool_instance'. Please check your configuration." # type: ignore[unreachable]
132
- raise ImproperConfigurationError(msg)
133
- await self.pool_instance.open()
134
- return self.pool_instance
135
-
136
- def provide_pool(self, *args: "Any", **kwargs: "Any") -> "Awaitable[AsyncConnectionPool]":
137
- """Create and return a connection pool.
138
-
139
- Returns:
140
- Awaitable[AsyncConnectionPool]: The configured connection pool.
141
- """
142
- return self.create_pool()
143
-
144
- @asynccontextmanager
145
- async def provide_connection(self, *args: "Any", **kwargs: "Any") -> "AsyncGenerator[PsycopgAsyncConnection, None]":
146
- """Create and provide a database connection.
147
-
148
- Yields:
149
- AsyncConnection: A database connection from the pool.
150
- """
151
- pool = await self.provide_pool(*args, **kwargs)
152
- async with pool, pool.connection() as connection:
153
- yield connection
154
-
155
- @asynccontextmanager
156
- async def provide_session(self, *args: "Any", **kwargs: "Any") -> "AsyncGenerator[PsycopgAsyncDriver, None]":
157
- """Create and provide a database session.
158
-
159
- Yields:
160
- PsycopgAsyncDriver: A driver instance with an active connection.
161
- """
162
- async with self.provide_connection(*args, **kwargs) as connection:
163
- yield self.driver_type(connection)
164
-
165
- async def close_pool(self) -> None:
166
- """Close the connection pool."""
167
- if self.pool_instance is not None:
168
- await self.pool_instance.close()
169
- self.pool_instance = None
@@ -1,56 +0,0 @@
1
- from dataclasses import dataclass
2
- from typing import TYPE_CHECKING, Generic, TypeVar, Union
3
-
4
- from sqlspec.base import GenericPoolConfig
5
- from sqlspec.typing import Empty
6
-
7
- if TYPE_CHECKING:
8
- from collections.abc import Callable
9
- from typing import Any
10
-
11
- from psycopg import AsyncConnection, Connection
12
- from psycopg_pool import AsyncConnectionPool, ConnectionPool
13
-
14
- from sqlspec.typing import EmptyType
15
-
16
-
17
- __all__ = ("PsycopgGenericPoolConfig",)
18
-
19
-
20
- ConnectionT = TypeVar("ConnectionT", bound="Union[Connection, AsyncConnection]")
21
- PoolT = TypeVar("PoolT", bound="Union[ConnectionPool, AsyncConnectionPool]")
22
-
23
-
24
- @dataclass
25
- class PsycopgGenericPoolConfig(GenericPoolConfig, Generic[ConnectionT, PoolT]):
26
- """Configuration for Psycopg connection pools.
27
-
28
- This class provides configuration options for both synchronous and asynchronous Psycopg
29
- database connection pools. It supports all standard Psycopg connection parameters and pool-specific
30
- settings.([1](https://www.psycopg.org/psycopg3/docs/api/pool.html))
31
- """
32
-
33
- conninfo: "Union[str, EmptyType]" = Empty
34
- """Connection string in libpq format"""
35
- kwargs: "Union[dict[str, Any], EmptyType]" = Empty
36
- """Additional connection parameters"""
37
- min_size: "Union[int, EmptyType]" = Empty
38
- """Minimum number of connections in the pool"""
39
- max_size: "Union[int, EmptyType]" = Empty
40
- """Maximum number of connections in the pool"""
41
- name: "Union[str, EmptyType]" = Empty
42
- """Name of the connection pool"""
43
- timeout: "Union[float, EmptyType]" = Empty
44
- """Timeout for acquiring connections"""
45
- max_waiting: "Union[int, EmptyType]" = Empty
46
- """Maximum number of waiting clients"""
47
- max_lifetime: "Union[float, EmptyType]" = Empty
48
- """Maximum connection lifetime"""
49
- max_idle: "Union[float, EmptyType]" = Empty
50
- """Maximum idle time for connections"""
51
- reconnect_timeout: "Union[float, EmptyType]" = Empty
52
- """Time between reconnection attempts"""
53
- num_workers: "Union[int, EmptyType]" = Empty
54
- """Number of background workers"""
55
- configure: "Union[Callable[[ConnectionT], None], EmptyType]" = Empty
56
- """Callback to configure new connections"""
@@ -1,168 +0,0 @@
1
- from contextlib import contextmanager
2
- from dataclasses import dataclass, field
3
- from typing import TYPE_CHECKING, Any, Optional
4
-
5
- from psycopg_pool import ConnectionPool
6
-
7
- from sqlspec.adapters.psycopg.config._common import PsycopgGenericPoolConfig
8
- from sqlspec.adapters.psycopg.driver import PsycopgSyncConnection, PsycopgSyncDriver
9
- from sqlspec.base import SyncDatabaseConfig
10
- from sqlspec.exceptions import ImproperConfigurationError
11
- from sqlspec.typing import dataclass_to_dict
12
-
13
- if TYPE_CHECKING:
14
- from collections.abc import Generator
15
-
16
-
17
- __all__ = (
18
- "PsycopgSyncConfig",
19
- "PsycopgSyncPoolConfig",
20
- )
21
-
22
-
23
- @dataclass
24
- class PsycopgSyncPoolConfig(PsycopgGenericPoolConfig[PsycopgSyncConnection, ConnectionPool]):
25
- """Sync Psycopg Pool Config"""
26
-
27
-
28
- @dataclass
29
- class PsycopgSyncConfig(SyncDatabaseConfig[PsycopgSyncConnection, ConnectionPool, PsycopgSyncDriver]):
30
- """Sync Psycopg database Configuration.
31
- This class provides the base configuration for Psycopg database connections, extending
32
- the generic database configuration with Psycopg-specific settings.([1](https://www.psycopg.org/psycopg3/docs/api/connections.html))
33
-
34
- The configuration supports all standard Psycopg connection parameters and can be used
35
- with both synchronous and asynchronous connections.([2](https://www.psycopg.org/psycopg3/docs/api/connections.html))
36
- """
37
-
38
- pool_config: "Optional[PsycopgSyncPoolConfig]" = None
39
- """Psycopg Pool configuration"""
40
- pool_instance: "Optional[ConnectionPool]" = None
41
- """Optional pool to use"""
42
- connection_type: "type[PsycopgSyncConnection]" = field(init=False, default_factory=lambda: PsycopgSyncConnection) # type: ignore[assignment]
43
- """Type of the connection object"""
44
- driver_type: "type[PsycopgSyncDriver]" = field(init=False, default_factory=lambda: PsycopgSyncDriver) # type: ignore[type-abstract,unused-ignore]
45
- """Type of the driver object"""
46
-
47
- @property
48
- def connection_config_dict(self) -> "dict[str, Any]":
49
- """Return the connection configuration as a dict.
50
-
51
- Returns:
52
- A string keyed dict of config kwargs for the psycopg.connect function.
53
-
54
- Raises:
55
- ImproperConfigurationError: If the connection configuration is not provided.
56
- """
57
- if self.pool_config:
58
- # Filter out pool-specific parameters
59
- pool_only_params = {
60
- "min_size",
61
- "max_size",
62
- "name",
63
- "timeout",
64
- "reconnect_timeout",
65
- "max_idle",
66
- "max_lifetime",
67
- }
68
- return dataclass_to_dict(
69
- self.pool_config,
70
- exclude_empty=True,
71
- convert_nested=False,
72
- exclude=pool_only_params.union({"pool_instance", "connection_type", "driver_type", "open"}),
73
- )
74
- msg = "You must provide a 'pool_config' for this adapter."
75
- raise ImproperConfigurationError(msg)
76
-
77
- @property
78
- def pool_config_dict(self) -> "dict[str, Any]":
79
- """Return the pool configuration as a dict.
80
-
81
- Raises:
82
- ImproperConfigurationError: If pool_config is not provided and instead pool_instance is used.
83
- """
84
- if self.pool_config:
85
- return dataclass_to_dict(
86
- self.pool_config,
87
- exclude_empty=True,
88
- convert_nested=False,
89
- exclude={"pool_instance", "connection_type", "driver_type", "open"},
90
- )
91
- msg = "'pool_config' methods can not be used when a 'pool_instance' is provided."
92
- raise ImproperConfigurationError(msg)
93
-
94
- def create_connection(self) -> "PsycopgSyncConnection":
95
- """Create and return a new psycopg connection from the pool.
96
-
97
- Returns:
98
- A Connection instance.
99
-
100
- Raises:
101
- ImproperConfigurationError: If the connection could not be created.
102
- """
103
- try:
104
- pool = self.provide_pool()
105
- return pool.getconn()
106
- except Exception as e:
107
- msg = f"Could not configure the Psycopg connection. Error: {e!s}"
108
- raise ImproperConfigurationError(msg) from e
109
-
110
- def create_pool(self) -> "ConnectionPool":
111
- """Create and return a connection pool.
112
-
113
- Returns:
114
- ConnectionPool: The configured connection pool instance.
115
-
116
- Raises:
117
- ImproperConfigurationError: If neither pool_config nor pool_instance is provided,
118
- or if the pool could not be configured.
119
- """
120
- if self.pool_instance is not None:
121
- return self.pool_instance
122
-
123
- if self.pool_config is None:
124
- msg = "One of 'pool_config' or 'pool_instance' must be provided."
125
- raise ImproperConfigurationError(msg)
126
-
127
- pool_config = self.pool_config_dict
128
- self.pool_instance = ConnectionPool(open=False, **pool_config)
129
- if self.pool_instance is None: # pyright: ignore[reportUnnecessaryComparison]
130
- msg = "Could not configure the 'pool_instance'. Please check your configuration." # type: ignore[unreachable]
131
- raise ImproperConfigurationError(msg)
132
- self.pool_instance.open()
133
- return self.pool_instance
134
-
135
- def provide_pool(self, *args: "Any", **kwargs: "Any") -> "ConnectionPool":
136
- """Create and return a connection pool.
137
-
138
- Returns:
139
- ConnectionPool: The configured connection pool instance.
140
- """
141
- return self.create_pool()
142
-
143
- @contextmanager
144
- def provide_connection(self, *args: "Any", **kwargs: "Any") -> "Generator[PsycopgSyncConnection, None, None]":
145
- """Create and provide a database connection.
146
-
147
- Yields:
148
- PsycopgSyncConnection: A database connection from the pool.
149
- """
150
- pool = self.provide_pool(*args, **kwargs)
151
- with pool, pool.connection() as connection:
152
- yield connection
153
-
154
- @contextmanager
155
- def provide_session(self, *args: "Any", **kwargs: "Any") -> "Generator[PsycopgSyncDriver, None, None]":
156
- """Create and provide a database session.
157
-
158
- Yields:
159
- PsycopgSyncDriver: A driver instance with an active connection.
160
- """
161
- with self.provide_connection(*args, **kwargs) as connection:
162
- yield self.driver_type(connection)
163
-
164
- def close_pool(self) -> None:
165
- """Close the connection pool."""
166
- if self.pool_instance is not None:
167
- self.pool_instance.close()
168
- self.pool_instance = None