sqlspec 0.13.1__py3-none-any.whl → 0.16.2__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 (185) hide show
  1. sqlspec/__init__.py +71 -8
  2. sqlspec/__main__.py +12 -0
  3. sqlspec/__metadata__.py +1 -3
  4. sqlspec/_serialization.py +1 -2
  5. sqlspec/_sql.py +930 -136
  6. sqlspec/_typing.py +278 -142
  7. sqlspec/adapters/adbc/__init__.py +4 -3
  8. sqlspec/adapters/adbc/_types.py +12 -0
  9. sqlspec/adapters/adbc/config.py +116 -285
  10. sqlspec/adapters/adbc/driver.py +462 -340
  11. sqlspec/adapters/aiosqlite/__init__.py +18 -3
  12. sqlspec/adapters/aiosqlite/_types.py +13 -0
  13. sqlspec/adapters/aiosqlite/config.py +202 -150
  14. sqlspec/adapters/aiosqlite/driver.py +226 -247
  15. sqlspec/adapters/asyncmy/__init__.py +18 -3
  16. sqlspec/adapters/asyncmy/_types.py +12 -0
  17. sqlspec/adapters/asyncmy/config.py +80 -199
  18. sqlspec/adapters/asyncmy/driver.py +257 -215
  19. sqlspec/adapters/asyncpg/__init__.py +19 -4
  20. sqlspec/adapters/asyncpg/_types.py +17 -0
  21. sqlspec/adapters/asyncpg/config.py +81 -214
  22. sqlspec/adapters/asyncpg/driver.py +284 -359
  23. sqlspec/adapters/bigquery/__init__.py +17 -3
  24. sqlspec/adapters/bigquery/_types.py +12 -0
  25. sqlspec/adapters/bigquery/config.py +191 -299
  26. sqlspec/adapters/bigquery/driver.py +474 -634
  27. sqlspec/adapters/duckdb/__init__.py +14 -3
  28. sqlspec/adapters/duckdb/_types.py +12 -0
  29. sqlspec/adapters/duckdb/config.py +414 -397
  30. sqlspec/adapters/duckdb/driver.py +342 -393
  31. sqlspec/adapters/oracledb/__init__.py +19 -5
  32. sqlspec/adapters/oracledb/_types.py +14 -0
  33. sqlspec/adapters/oracledb/config.py +123 -458
  34. sqlspec/adapters/oracledb/driver.py +505 -531
  35. sqlspec/adapters/psqlpy/__init__.py +13 -3
  36. sqlspec/adapters/psqlpy/_types.py +11 -0
  37. sqlspec/adapters/psqlpy/config.py +93 -307
  38. sqlspec/adapters/psqlpy/driver.py +504 -213
  39. sqlspec/adapters/psycopg/__init__.py +19 -5
  40. sqlspec/adapters/psycopg/_types.py +17 -0
  41. sqlspec/adapters/psycopg/config.py +143 -472
  42. sqlspec/adapters/psycopg/driver.py +704 -825
  43. sqlspec/adapters/sqlite/__init__.py +14 -3
  44. sqlspec/adapters/sqlite/_types.py +11 -0
  45. sqlspec/adapters/sqlite/config.py +208 -142
  46. sqlspec/adapters/sqlite/driver.py +263 -278
  47. sqlspec/base.py +105 -9
  48. sqlspec/{statement/builder → builder}/__init__.py +12 -14
  49. sqlspec/{statement/builder/base.py → builder/_base.py} +184 -86
  50. sqlspec/{statement/builder/column.py → builder/_column.py} +97 -60
  51. sqlspec/{statement/builder/ddl.py → builder/_ddl.py} +61 -131
  52. sqlspec/{statement/builder → builder}/_ddl_utils.py +4 -10
  53. sqlspec/{statement/builder/delete.py → builder/_delete.py} +10 -30
  54. sqlspec/builder/_insert.py +421 -0
  55. sqlspec/builder/_merge.py +71 -0
  56. sqlspec/{statement/builder → builder}/_parsing_utils.py +49 -26
  57. sqlspec/builder/_select.py +170 -0
  58. sqlspec/{statement/builder/update.py → builder/_update.py} +16 -20
  59. sqlspec/builder/mixins/__init__.py +55 -0
  60. sqlspec/builder/mixins/_cte_and_set_ops.py +222 -0
  61. sqlspec/{statement/builder/mixins/_delete_from.py → builder/mixins/_delete_operations.py} +8 -1
  62. sqlspec/builder/mixins/_insert_operations.py +244 -0
  63. sqlspec/{statement/builder/mixins/_join.py → builder/mixins/_join_operations.py} +45 -13
  64. sqlspec/{statement/builder/mixins/_merge_clauses.py → builder/mixins/_merge_operations.py} +188 -30
  65. sqlspec/builder/mixins/_order_limit_operations.py +135 -0
  66. sqlspec/builder/mixins/_pivot_operations.py +153 -0
  67. sqlspec/builder/mixins/_select_operations.py +604 -0
  68. sqlspec/builder/mixins/_update_operations.py +202 -0
  69. sqlspec/builder/mixins/_where_clause.py +644 -0
  70. sqlspec/cli.py +247 -0
  71. sqlspec/config.py +183 -138
  72. sqlspec/core/__init__.py +63 -0
  73. sqlspec/core/cache.py +871 -0
  74. sqlspec/core/compiler.py +417 -0
  75. sqlspec/core/filters.py +830 -0
  76. sqlspec/core/hashing.py +310 -0
  77. sqlspec/core/parameters.py +1237 -0
  78. sqlspec/core/result.py +677 -0
  79. sqlspec/{statement → core}/splitter.py +321 -191
  80. sqlspec/core/statement.py +676 -0
  81. sqlspec/driver/__init__.py +7 -10
  82. sqlspec/driver/_async.py +422 -163
  83. sqlspec/driver/_common.py +545 -287
  84. sqlspec/driver/_sync.py +426 -160
  85. sqlspec/driver/mixins/__init__.py +2 -13
  86. sqlspec/driver/mixins/_result_tools.py +193 -0
  87. sqlspec/driver/mixins/_sql_translator.py +65 -14
  88. sqlspec/exceptions.py +5 -252
  89. sqlspec/extensions/aiosql/adapter.py +93 -96
  90. sqlspec/extensions/litestar/__init__.py +2 -1
  91. sqlspec/extensions/litestar/cli.py +48 -0
  92. sqlspec/extensions/litestar/config.py +0 -1
  93. sqlspec/extensions/litestar/handlers.py +15 -26
  94. sqlspec/extensions/litestar/plugin.py +21 -16
  95. sqlspec/extensions/litestar/providers.py +17 -52
  96. sqlspec/loader.py +423 -104
  97. sqlspec/migrations/__init__.py +35 -0
  98. sqlspec/migrations/base.py +414 -0
  99. sqlspec/migrations/commands.py +443 -0
  100. sqlspec/migrations/loaders.py +402 -0
  101. sqlspec/migrations/runner.py +213 -0
  102. sqlspec/migrations/tracker.py +140 -0
  103. sqlspec/migrations/utils.py +129 -0
  104. sqlspec/protocols.py +51 -186
  105. sqlspec/storage/__init__.py +1 -1
  106. sqlspec/storage/backends/base.py +37 -40
  107. sqlspec/storage/backends/fsspec.py +136 -112
  108. sqlspec/storage/backends/obstore.py +138 -160
  109. sqlspec/storage/capabilities.py +5 -4
  110. sqlspec/storage/registry.py +57 -106
  111. sqlspec/typing.py +136 -115
  112. sqlspec/utils/__init__.py +2 -2
  113. sqlspec/utils/correlation.py +0 -3
  114. sqlspec/utils/deprecation.py +6 -6
  115. sqlspec/utils/fixtures.py +6 -6
  116. sqlspec/utils/logging.py +0 -2
  117. sqlspec/utils/module_loader.py +7 -12
  118. sqlspec/utils/singleton.py +0 -1
  119. sqlspec/utils/sync_tools.py +17 -38
  120. sqlspec/utils/text.py +12 -51
  121. sqlspec/utils/type_guards.py +482 -235
  122. {sqlspec-0.13.1.dist-info → sqlspec-0.16.2.dist-info}/METADATA +7 -2
  123. sqlspec-0.16.2.dist-info/RECORD +134 -0
  124. sqlspec-0.16.2.dist-info/entry_points.txt +2 -0
  125. sqlspec/driver/connection.py +0 -207
  126. sqlspec/driver/mixins/_csv_writer.py +0 -91
  127. sqlspec/driver/mixins/_pipeline.py +0 -512
  128. sqlspec/driver/mixins/_result_utils.py +0 -140
  129. sqlspec/driver/mixins/_storage.py +0 -926
  130. sqlspec/driver/mixins/_type_coercion.py +0 -130
  131. sqlspec/driver/parameters.py +0 -138
  132. sqlspec/service/__init__.py +0 -4
  133. sqlspec/service/_util.py +0 -147
  134. sqlspec/service/base.py +0 -1131
  135. sqlspec/service/pagination.py +0 -26
  136. sqlspec/statement/__init__.py +0 -21
  137. sqlspec/statement/builder/insert.py +0 -288
  138. sqlspec/statement/builder/merge.py +0 -95
  139. sqlspec/statement/builder/mixins/__init__.py +0 -65
  140. sqlspec/statement/builder/mixins/_aggregate_functions.py +0 -250
  141. sqlspec/statement/builder/mixins/_case_builder.py +0 -91
  142. sqlspec/statement/builder/mixins/_common_table_expr.py +0 -90
  143. sqlspec/statement/builder/mixins/_from.py +0 -63
  144. sqlspec/statement/builder/mixins/_group_by.py +0 -118
  145. sqlspec/statement/builder/mixins/_having.py +0 -35
  146. sqlspec/statement/builder/mixins/_insert_from_select.py +0 -47
  147. sqlspec/statement/builder/mixins/_insert_into.py +0 -36
  148. sqlspec/statement/builder/mixins/_insert_values.py +0 -67
  149. sqlspec/statement/builder/mixins/_limit_offset.py +0 -53
  150. sqlspec/statement/builder/mixins/_order_by.py +0 -46
  151. sqlspec/statement/builder/mixins/_pivot.py +0 -79
  152. sqlspec/statement/builder/mixins/_returning.py +0 -37
  153. sqlspec/statement/builder/mixins/_select_columns.py +0 -61
  154. sqlspec/statement/builder/mixins/_set_ops.py +0 -122
  155. sqlspec/statement/builder/mixins/_unpivot.py +0 -77
  156. sqlspec/statement/builder/mixins/_update_from.py +0 -55
  157. sqlspec/statement/builder/mixins/_update_set.py +0 -94
  158. sqlspec/statement/builder/mixins/_update_table.py +0 -29
  159. sqlspec/statement/builder/mixins/_where.py +0 -401
  160. sqlspec/statement/builder/mixins/_window_functions.py +0 -86
  161. sqlspec/statement/builder/select.py +0 -221
  162. sqlspec/statement/filters.py +0 -596
  163. sqlspec/statement/parameter_manager.py +0 -220
  164. sqlspec/statement/parameters.py +0 -867
  165. sqlspec/statement/pipelines/__init__.py +0 -210
  166. sqlspec/statement/pipelines/analyzers/__init__.py +0 -9
  167. sqlspec/statement/pipelines/analyzers/_analyzer.py +0 -646
  168. sqlspec/statement/pipelines/context.py +0 -115
  169. sqlspec/statement/pipelines/transformers/__init__.py +0 -7
  170. sqlspec/statement/pipelines/transformers/_expression_simplifier.py +0 -88
  171. sqlspec/statement/pipelines/transformers/_literal_parameterizer.py +0 -1247
  172. sqlspec/statement/pipelines/transformers/_remove_comments_and_hints.py +0 -76
  173. sqlspec/statement/pipelines/validators/__init__.py +0 -23
  174. sqlspec/statement/pipelines/validators/_dml_safety.py +0 -290
  175. sqlspec/statement/pipelines/validators/_parameter_style.py +0 -370
  176. sqlspec/statement/pipelines/validators/_performance.py +0 -718
  177. sqlspec/statement/pipelines/validators/_security.py +0 -967
  178. sqlspec/statement/result.py +0 -435
  179. sqlspec/statement/sql.py +0 -1704
  180. sqlspec/statement/sql_compiler.py +0 -140
  181. sqlspec/utils/cached_property.py +0 -25
  182. sqlspec-0.13.1.dist-info/RECORD +0 -150
  183. {sqlspec-0.13.1.dist-info → sqlspec-0.16.2.dist-info}/WHEEL +0 -0
  184. {sqlspec-0.13.1.dist-info → sqlspec-0.16.2.dist-info}/licenses/LICENSE +0 -0
  185. {sqlspec-0.13.1.dist-info → sqlspec-0.16.2.dist-info}/licenses/NOTICE +0 -0
@@ -1,6 +1,16 @@
1
1
  """Psqlpy adapter for SQLSpec."""
2
2
 
3
- from sqlspec.adapters.psqlpy.config import CONNECTION_FIELDS, POOL_FIELDS, PsqlpyConfig
4
- from sqlspec.adapters.psqlpy.driver import PsqlpyConnection, PsqlpyDriver
3
+ from sqlspec.adapters.psqlpy._types import PsqlpyConnection
4
+ from sqlspec.adapters.psqlpy.config import PsqlpyConfig, PsqlpyConnectionParams, PsqlpyPoolParams
5
+ from sqlspec.adapters.psqlpy.driver import PsqlpyCursor, PsqlpyDriver, PsqlpyExceptionHandler, psqlpy_statement_config
5
6
 
6
- __all__ = ("CONNECTION_FIELDS", "POOL_FIELDS", "PsqlpyConfig", "PsqlpyConnection", "PsqlpyDriver")
7
+ __all__ = (
8
+ "PsqlpyConfig",
9
+ "PsqlpyConnection",
10
+ "PsqlpyConnectionParams",
11
+ "PsqlpyCursor",
12
+ "PsqlpyDriver",
13
+ "PsqlpyExceptionHandler",
14
+ "PsqlpyPoolParams",
15
+ "psqlpy_statement_config",
16
+ )
@@ -0,0 +1,11 @@
1
+ from typing import TYPE_CHECKING
2
+
3
+ if TYPE_CHECKING:
4
+ from psqlpy import Connection
5
+ from typing_extensions import TypeAlias
6
+
7
+ PsqlpyConnection: TypeAlias = Connection
8
+ else:
9
+ from psqlpy import Connection as PsqlpyConnection
10
+
11
+ __all__ = ("PsqlpyConnection",)
@@ -3,334 +3,128 @@
3
3
  import logging
4
4
  from collections.abc import AsyncGenerator
5
5
  from contextlib import asynccontextmanager
6
- from typing import TYPE_CHECKING, Any, ClassVar, Optional
6
+ from typing import TYPE_CHECKING, Any, ClassVar, Optional, TypedDict, Union
7
7
 
8
8
  from psqlpy import ConnectionPool
9
+ from typing_extensions import NotRequired
9
10
 
10
- from sqlspec.adapters.psqlpy.driver import PsqlpyConnection, PsqlpyDriver
11
+ from sqlspec.adapters.psqlpy._types import PsqlpyConnection
12
+ from sqlspec.adapters.psqlpy.driver import PsqlpyCursor, PsqlpyDriver, psqlpy_statement_config
11
13
  from sqlspec.config import AsyncDatabaseConfig
12
- from sqlspec.statement.sql import SQLConfig
13
- from sqlspec.typing import DictRow, Empty
14
+ from sqlspec.core.statement import StatementConfig
14
15
 
15
16
  if TYPE_CHECKING:
16
17
  from collections.abc import Callable
17
18
 
18
- from sqlglot.dialects.dialect import DialectType
19
19
 
20
20
  logger = logging.getLogger("sqlspec.adapters.psqlpy")
21
21
 
22
- CONNECTION_FIELDS = frozenset(
23
- {
24
- "dsn",
25
- "username",
26
- "password",
27
- "db_name",
28
- "host",
29
- "port",
30
- "connect_timeout_sec",
31
- "connect_timeout_nanosec",
32
- "tcp_user_timeout_sec",
33
- "tcp_user_timeout_nanosec",
34
- "keepalives",
35
- "keepalives_idle_sec",
36
- "keepalives_idle_nanosec",
37
- "keepalives_interval_sec",
38
- "keepalives_interval_nanosec",
39
- "keepalives_retries",
40
- "ssl_mode",
41
- "ca_file",
42
- "target_session_attrs",
43
- "options",
44
- "application_name",
45
- "client_encoding",
46
- "gssencmode",
47
- "sslnegotiation",
48
- "sslcompression",
49
- "sslcert",
50
- "sslkey",
51
- "sslpassword",
52
- "sslrootcert",
53
- "sslcrl",
54
- "require_auth",
55
- "channel_binding",
56
- "krbsrvname",
57
- "gsslib",
58
- "gssdelegation",
59
- "service",
60
- "load_balance_hosts",
61
- }
62
- )
63
-
64
- POOL_FIELDS = CONNECTION_FIELDS.union({"hosts", "ports", "conn_recycling_method", "max_db_pool_size", "configure"})
65
-
66
- __all__ = ("CONNECTION_FIELDS", "POOL_FIELDS", "PsqlpyConfig")
22
+
23
+ class PsqlpyConnectionParams(TypedDict, total=False):
24
+ """Psqlpy connection parameters."""
25
+
26
+ dsn: NotRequired[str]
27
+ username: NotRequired[str]
28
+ password: NotRequired[str]
29
+ db_name: NotRequired[str]
30
+ host: NotRequired[str]
31
+ port: NotRequired[int]
32
+ connect_timeout_sec: NotRequired[int]
33
+ connect_timeout_nanosec: NotRequired[int]
34
+ tcp_user_timeout_sec: NotRequired[int]
35
+ tcp_user_timeout_nanosec: NotRequired[int]
36
+ keepalives: NotRequired[bool]
37
+ keepalives_idle_sec: NotRequired[int]
38
+ keepalives_idle_nanosec: NotRequired[int]
39
+ keepalives_interval_sec: NotRequired[int]
40
+ keepalives_interval_nanosec: NotRequired[int]
41
+ keepalives_retries: NotRequired[int]
42
+ ssl_mode: NotRequired[str]
43
+ ca_file: NotRequired[str]
44
+ target_session_attrs: NotRequired[str]
45
+ options: NotRequired[str]
46
+ application_name: NotRequired[str]
47
+ client_encoding: NotRequired[str]
48
+ gssencmode: NotRequired[str]
49
+ sslnegotiation: NotRequired[str]
50
+ sslcompression: NotRequired[str]
51
+ sslcert: NotRequired[str]
52
+ sslkey: NotRequired[str]
53
+ sslpassword: NotRequired[str]
54
+ sslrootcert: NotRequired[str]
55
+ sslcrl: NotRequired[str]
56
+ require_auth: NotRequired[str]
57
+ channel_binding: NotRequired[str]
58
+ krbsrvname: NotRequired[str]
59
+ gsslib: NotRequired[str]
60
+ gssdelegation: NotRequired[str]
61
+ service: NotRequired[str]
62
+ load_balance_hosts: NotRequired[str]
63
+
64
+
65
+ class PsqlpyPoolParams(PsqlpyConnectionParams, total=False):
66
+ """Psqlpy pool parameters."""
67
+
68
+ hosts: NotRequired[list[str]]
69
+ ports: NotRequired[list[int]]
70
+ conn_recycling_method: NotRequired[str]
71
+ max_db_pool_size: NotRequired[int]
72
+ configure: NotRequired["Callable[..., Any]"]
73
+ extra: NotRequired[dict[str, Any]]
74
+
75
+
76
+ __all__ = ("PsqlpyConfig", "PsqlpyConnectionParams", "PsqlpyCursor", "PsqlpyPoolParams")
67
77
 
68
78
 
69
79
  class PsqlpyConfig(AsyncDatabaseConfig[PsqlpyConnection, ConnectionPool, PsqlpyDriver]):
70
80
  """Configuration for Psqlpy asynchronous database connections with direct field-based configuration."""
71
81
 
72
- __slots__ = (
73
- "_dialect",
74
- "application_name",
75
- "ca_file",
76
- "channel_binding",
77
- "client_encoding",
78
- "configure",
79
- "conn_recycling_method",
80
- "connect_timeout_nanosec",
81
- "connect_timeout_sec",
82
- "db_name",
83
- "default_row_type",
84
- "dsn",
85
- "extras",
86
- "gssdelegation",
87
- "gssencmode",
88
- "gsslib",
89
- "host",
90
- "hosts",
91
- "keepalives",
92
- "keepalives_idle_nanosec",
93
- "keepalives_idle_sec",
94
- "keepalives_interval_nanosec",
95
- "keepalives_interval_sec",
96
- "keepalives_retries",
97
- "krbsrvname",
98
- "load_balance_hosts",
99
- "max_db_pool_size",
100
- "options",
101
- "password",
102
- "pool_instance",
103
- "port",
104
- "ports",
105
- "require_auth",
106
- "service",
107
- "ssl_mode",
108
- "sslcert",
109
- "sslcompression",
110
- "sslcrl",
111
- "sslkey",
112
- "sslnegotiation",
113
- "sslpassword",
114
- "sslrootcert",
115
- "statement_config",
116
- "target_session_attrs",
117
- "tcp_user_timeout_nanosec",
118
- "tcp_user_timeout_sec",
119
- "username",
120
- )
121
-
122
- is_async: ClassVar[bool] = True
123
- supports_connection_pooling: ClassVar[bool] = True
124
-
125
- driver_type: type[PsqlpyDriver] = PsqlpyDriver
126
- connection_type: type[PsqlpyConnection] = PsqlpyConnection
127
- # Parameter style support information
128
- supported_parameter_styles: ClassVar[tuple[str, ...]] = ("numeric",)
129
- """Psqlpy only supports $1, $2, ... (numeric) parameter style."""
130
-
131
- preferred_parameter_style: ClassVar[str] = "numeric"
132
- """Psqlpy's native parameter style is $1, $2, ... (numeric)."""
82
+ driver_type: ClassVar[type[PsqlpyDriver]] = PsqlpyDriver
83
+ connection_type: "ClassVar[type[PsqlpyConnection]]" = PsqlpyConnection
133
84
 
134
85
  def __init__(
135
86
  self,
136
- statement_config: Optional[SQLConfig] = None,
137
- default_row_type: type[DictRow] = DictRow,
138
- # Connection parameters
139
- dsn: Optional[str] = None,
140
- username: Optional[str] = None,
141
- password: Optional[str] = None,
142
- db_name: Optional[str] = None,
143
- host: Optional[str] = None,
144
- port: Optional[int] = None,
145
- hosts: Optional[list[str]] = None,
146
- ports: Optional[list[int]] = None,
147
- connect_timeout_sec: Optional[int] = None,
148
- connect_timeout_nanosec: Optional[int] = None,
149
- tcp_user_timeout_sec: Optional[int] = None,
150
- tcp_user_timeout_nanosec: Optional[int] = None,
151
- keepalives: Optional[bool] = None,
152
- keepalives_idle_sec: Optional[int] = None,
153
- keepalives_idle_nanosec: Optional[int] = None,
154
- keepalives_interval_sec: Optional[int] = None,
155
- keepalives_interval_nanosec: Optional[int] = None,
156
- keepalives_retries: Optional[int] = None,
157
- ssl_mode: Optional[str] = None,
158
- ca_file: Optional[str] = None,
159
- target_session_attrs: Optional[str] = None,
160
- options: Optional[str] = None,
161
- application_name: Optional[str] = None,
162
- client_encoding: Optional[str] = None,
163
- gssencmode: Optional[str] = None,
164
- sslnegotiation: Optional[str] = None,
165
- sslcompression: Optional[bool] = None,
166
- sslcert: Optional[str] = None,
167
- sslkey: Optional[str] = None,
168
- sslpassword: Optional[str] = None,
169
- sslrootcert: Optional[str] = None,
170
- sslcrl: Optional[str] = None,
171
- require_auth: Optional[str] = None,
172
- channel_binding: Optional[str] = None,
173
- krbsrvname: Optional[str] = None,
174
- gsslib: Optional[str] = None,
175
- gssdelegation: Optional[bool] = None,
176
- service: Optional[str] = None,
177
- load_balance_hosts: Optional[str] = None,
178
- # Pool parameters
179
- conn_recycling_method: Optional[str] = None,
180
- max_db_pool_size: Optional[int] = None,
181
- configure: Optional["Callable[[ConnectionPool], None]"] = None,
87
+ *,
88
+ pool_config: Optional[Union[PsqlpyPoolParams, dict[str, Any]]] = None,
89
+ statement_config: Optional[StatementConfig] = None,
182
90
  pool_instance: Optional[ConnectionPool] = None,
183
- **kwargs: Any,
91
+ migration_config: Optional[dict[str, Any]] = None,
184
92
  ) -> None:
185
93
  """Initialize Psqlpy asynchronous configuration.
186
94
 
187
95
  Args:
188
- statement_config: Default SQL statement configuration
189
- default_row_type: Default row type for results
190
- dsn: DSN of the PostgreSQL database
191
- username: Username of the user in the PostgreSQL
192
- password: Password of the user in the PostgreSQL
193
- db_name: Name of the database in PostgreSQL
194
- host: Host of the PostgreSQL (use for single host)
195
- port: Port of the PostgreSQL (use for single host)
196
- hosts: List of hosts of the PostgreSQL (use for multiple hosts)
197
- ports: List of ports of the PostgreSQL (use for multiple hosts)
198
- connect_timeout_sec: The time limit in seconds applied to each socket-level connection attempt
199
- connect_timeout_nanosec: Nanoseconds for connection timeout, can be used only with connect_timeout_sec
200
- tcp_user_timeout_sec: The time limit that transmitted data may remain unacknowledged before a connection is forcibly closed
201
- tcp_user_timeout_nanosec: Nanoseconds for tcp_user_timeout, can be used only with tcp_user_timeout_sec
202
- keepalives: Controls the use of TCP keepalive. Defaults to True (on)
203
- keepalives_idle_sec: The number of seconds of inactivity after which a keepalive message is sent to the server
204
- keepalives_idle_nanosec: Nanoseconds for keepalives_idle_sec
205
- keepalives_interval_sec: The time interval between TCP keepalive probes
206
- keepalives_interval_nanosec: Nanoseconds for keepalives_interval_sec
207
- keepalives_retries: The maximum number of TCP keepalive probes that will be sent before dropping a connection
208
- ssl_mode: SSL mode (disable, prefer, require, verify-ca, verify-full)
209
- ca_file: Path to ca_file for SSL
210
- target_session_attrs: Specifies requirements of the session (e.g., 'read-write', 'read-only', 'primary', 'standby')
211
- options: Command line options used to configure the server
212
- application_name: Sets the application_name parameter on the server
213
- client_encoding: Sets the client_encoding parameter
214
- gssencmode: GSS encryption mode (disable, prefer, require)
215
- sslnegotiation: SSL negotiation mode (postgres, direct)
216
- sslcompression: Whether to use SSL compression
217
- sslcert: Client SSL certificate file
218
- sslkey: Client SSL private key file
219
- sslpassword: Password for the SSL private key
220
- sslrootcert: SSL root certificate file
221
- sslcrl: SSL certificate revocation list file
222
- require_auth: Authentication method requirements
223
- channel_binding: Channel binding preference (disable, prefer, require)
224
- krbsrvname: Kerberos service name
225
- gsslib: GSS library to use
226
- gssdelegation: Forward GSS credentials to server
227
- service: Service name for additional parameters
228
- load_balance_hosts: Controls the order in which the client tries to connect to the available hosts and addresses ('disable' or 'random')
229
- conn_recycling_method: How a connection is recycled
230
- max_db_pool_size: Maximum size of the connection pool. Defaults to 10
231
- configure: Callback to configure new connections
96
+ pool_config: Pool configuration parameters (TypedDict or dict)
232
97
  pool_instance: Existing connection pool instance to use
233
- **kwargs: Additional parameters (stored in extras)
234
- """
235
- # Store connection parameters as instance attributes
236
- self.dsn = dsn
237
- self.username = username
238
- self.password = password
239
- self.db_name = db_name
240
- self.host = host
241
- self.port = port
242
- self.hosts = hosts
243
- self.ports = ports
244
- self.connect_timeout_sec = connect_timeout_sec
245
- self.connect_timeout_nanosec = connect_timeout_nanosec
246
- self.tcp_user_timeout_sec = tcp_user_timeout_sec
247
- self.tcp_user_timeout_nanosec = tcp_user_timeout_nanosec
248
- self.keepalives = keepalives
249
- self.keepalives_idle_sec = keepalives_idle_sec
250
- self.keepalives_idle_nanosec = keepalives_idle_nanosec
251
- self.keepalives_interval_sec = keepalives_interval_sec
252
- self.keepalives_interval_nanosec = keepalives_interval_nanosec
253
- self.keepalives_retries = keepalives_retries
254
- self.ssl_mode = ssl_mode
255
- self.ca_file = ca_file
256
- self.target_session_attrs = target_session_attrs
257
- self.options = options
258
- self.application_name = application_name
259
- self.client_encoding = client_encoding
260
- self.gssencmode = gssencmode
261
- self.sslnegotiation = sslnegotiation
262
- self.sslcompression = sslcompression
263
- self.sslcert = sslcert
264
- self.sslkey = sslkey
265
- self.sslpassword = sslpassword
266
- self.sslrootcert = sslrootcert
267
- self.sslcrl = sslcrl
268
- self.require_auth = require_auth
269
- self.channel_binding = channel_binding
270
- self.krbsrvname = krbsrvname
271
- self.gsslib = gsslib
272
- self.gssdelegation = gssdelegation
273
- self.service = service
274
- self.load_balance_hosts = load_balance_hosts
275
-
276
- # Store pool parameters as instance attributes
277
- self.conn_recycling_method = conn_recycling_method
278
- self.max_db_pool_size = max_db_pool_size
279
- self.configure = configure
280
-
281
- self.extras = kwargs or {}
282
-
283
- # Store other config
284
- self.statement_config = statement_config or SQLConfig()
285
- self.default_row_type = default_row_type
286
- self.pool_instance: Optional[ConnectionPool] = pool_instance
287
- self._dialect: DialectType = None
288
-
289
- super().__init__()
290
-
291
- @property
292
- def connection_config_dict(self) -> dict[str, Any]:
293
- """Return the connection configuration as a dict for psqlpy.Connection.
294
-
295
- This method filters out pool-specific parameters that are not valid for psqlpy.Connection.
98
+ statement_config: Default SQL statement configuration
99
+ migration_config: Migration configuration
296
100
  """
297
- # Gather non-None connection parameters
298
- config = {
299
- field: getattr(self, field)
300
- for field in CONNECTION_FIELDS
301
- if getattr(self, field, None) is not None and getattr(self, field) is not Empty
302
- }
303
-
304
- config.update(self.extras)
305
-
306
- return config
307
-
308
- @property
309
- def pool_config_dict(self) -> dict[str, Any]:
310
- """Return the full pool configuration as a dict for psqlpy.ConnectionPool.
101
+ processed_pool_config: dict[str, Any] = dict(pool_config) if pool_config else {}
102
+ if "extra" in processed_pool_config:
103
+ extras = processed_pool_config.pop("extra")
104
+ processed_pool_config.update(extras)
105
+ super().__init__(
106
+ pool_config=processed_pool_config,
107
+ pool_instance=pool_instance,
108
+ migration_config=migration_config,
109
+ statement_config=statement_config or psqlpy_statement_config,
110
+ )
111
+
112
+ def _get_pool_config_dict(self) -> dict[str, Any]:
113
+ """Get pool configuration as plain dict for external library.
311
114
 
312
115
  Returns:
313
- A dictionary containing all pool configuration parameters.
116
+ Dictionary with pool parameters, filtering out None values.
314
117
  """
315
- # Gather non-None parameters from all fields (connection + pool)
316
- config = {
317
- field: getattr(self, field)
318
- for field in POOL_FIELDS
319
- if getattr(self, field, None) is not None and getattr(self, field) is not Empty
320
- }
321
-
322
- # Merge extras parameters
323
- config.update(self.extras)
324
-
325
- return config
118
+ return {k: v for k, v in self.pool_config.items() if v is not None}
326
119
 
327
120
  async def _create_pool(self) -> "ConnectionPool":
328
121
  """Create the actual async connection pool."""
329
122
  logger.info("Creating psqlpy connection pool", extra={"adapter": "psqlpy"})
330
123
 
331
124
  try:
332
- config = self.pool_config_dict
333
- pool = ConnectionPool(**config) # pyright: ignore
125
+ config = self._get_pool_config_dict()
126
+
127
+ pool = ConnectionPool(**config)
334
128
  logger.info("Psqlpy connection pool created successfully", extra={"adapter": "psqlpy"})
335
129
  except Exception as e:
336
130
  logger.exception("Failed to create psqlpy connection pool", extra={"adapter": "psqlpy", "error": str(e)})
@@ -380,29 +174,21 @@ class PsqlpyConfig(AsyncDatabaseConfig[PsqlpyConnection, ConnectionPool, PsqlpyD
380
174
  yield conn
381
175
 
382
176
  @asynccontextmanager
383
- async def provide_session(self, *args: Any, **kwargs: Any) -> AsyncGenerator[PsqlpyDriver, None]:
177
+ async def provide_session(
178
+ self, *args: Any, statement_config: "Optional[StatementConfig]" = None, **kwargs: Any
179
+ ) -> AsyncGenerator[PsqlpyDriver, None]:
384
180
  """Provide an async driver session context manager.
385
181
 
386
182
  Args:
387
183
  *args: Additional arguments.
184
+ statement_config: Optional statement configuration override.
388
185
  **kwargs: Additional keyword arguments.
389
186
 
390
187
  Yields:
391
188
  A PsqlpyDriver instance.
392
189
  """
393
190
  async with self.provide_connection(*args, **kwargs) as conn:
394
- statement_config = self.statement_config
395
- # Inject parameter style info if not already set
396
- if statement_config.allowed_parameter_styles is None:
397
- from dataclasses import replace
398
-
399
- statement_config = replace(
400
- statement_config,
401
- allowed_parameter_styles=self.supported_parameter_styles,
402
- target_parameter_style=self.preferred_parameter_style,
403
- )
404
- driver = self.driver_type(connection=conn, config=statement_config)
405
- yield driver
191
+ yield self.driver_type(connection=conn, statement_config=statement_config or self.statement_config)
406
192
 
407
193
  async def provide_pool(self, *args: Any, **kwargs: Any) -> ConnectionPool:
408
194
  """Provide async pool instance.
@@ -424,5 +210,5 @@ class PsqlpyConfig(AsyncDatabaseConfig[PsqlpyConnection, ConnectionPool, PsqlpyD
424
210
  Dictionary mapping type names to types.
425
211
  """
426
212
  namespace = super().get_signature_namespace()
427
- namespace.update({"PsqlpyConnection": PsqlpyConnection})
213
+ namespace.update({"PsqlpyConnection": PsqlpyConnection, "PsqlpyCursor": PsqlpyCursor})
428
214
  return namespace