sqlspec 0.14.1__py3-none-any.whl → 0.15.0__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 (158) hide show
  1. sqlspec/__init__.py +50 -25
  2. sqlspec/__main__.py +1 -1
  3. sqlspec/__metadata__.py +1 -3
  4. sqlspec/_serialization.py +1 -2
  5. sqlspec/_sql.py +256 -120
  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 +115 -260
  10. sqlspec/adapters/adbc/driver.py +462 -367
  11. sqlspec/adapters/aiosqlite/__init__.py +18 -3
  12. sqlspec/adapters/aiosqlite/_types.py +13 -0
  13. sqlspec/adapters/aiosqlite/config.py +199 -129
  14. sqlspec/adapters/aiosqlite/driver.py +230 -269
  15. sqlspec/adapters/asyncmy/__init__.py +18 -3
  16. sqlspec/adapters/asyncmy/_types.py +12 -0
  17. sqlspec/adapters/asyncmy/config.py +80 -168
  18. sqlspec/adapters/asyncmy/driver.py +260 -225
  19. sqlspec/adapters/asyncpg/__init__.py +19 -4
  20. sqlspec/adapters/asyncpg/_types.py +17 -0
  21. sqlspec/adapters/asyncpg/config.py +82 -181
  22. sqlspec/adapters/asyncpg/driver.py +285 -383
  23. sqlspec/adapters/bigquery/__init__.py +17 -3
  24. sqlspec/adapters/bigquery/_types.py +12 -0
  25. sqlspec/adapters/bigquery/config.py +191 -258
  26. sqlspec/adapters/bigquery/driver.py +474 -646
  27. sqlspec/adapters/duckdb/__init__.py +14 -3
  28. sqlspec/adapters/duckdb/_types.py +12 -0
  29. sqlspec/adapters/duckdb/config.py +415 -351
  30. sqlspec/adapters/duckdb/driver.py +343 -413
  31. sqlspec/adapters/oracledb/__init__.py +19 -5
  32. sqlspec/adapters/oracledb/_types.py +14 -0
  33. sqlspec/adapters/oracledb/config.py +123 -379
  34. sqlspec/adapters/oracledb/driver.py +507 -560
  35. sqlspec/adapters/psqlpy/__init__.py +13 -3
  36. sqlspec/adapters/psqlpy/_types.py +11 -0
  37. sqlspec/adapters/psqlpy/config.py +93 -254
  38. sqlspec/adapters/psqlpy/driver.py +505 -234
  39. sqlspec/adapters/psycopg/__init__.py +19 -5
  40. sqlspec/adapters/psycopg/_types.py +17 -0
  41. sqlspec/adapters/psycopg/config.py +143 -403
  42. sqlspec/adapters/psycopg/driver.py +706 -872
  43. sqlspec/adapters/sqlite/__init__.py +14 -3
  44. sqlspec/adapters/sqlite/_types.py +11 -0
  45. sqlspec/adapters/sqlite/config.py +202 -118
  46. sqlspec/adapters/sqlite/driver.py +264 -303
  47. sqlspec/base.py +105 -9
  48. sqlspec/{statement/builder → builder}/__init__.py +12 -14
  49. sqlspec/{statement/builder → builder}/_base.py +120 -55
  50. sqlspec/{statement/builder → builder}/_column.py +17 -6
  51. sqlspec/{statement/builder → builder}/_ddl.py +46 -79
  52. sqlspec/{statement/builder → builder}/_ddl_utils.py +5 -10
  53. sqlspec/{statement/builder → builder}/_delete.py +6 -25
  54. sqlspec/{statement/builder → builder}/_insert.py +6 -64
  55. sqlspec/builder/_merge.py +56 -0
  56. sqlspec/{statement/builder → builder}/_parsing_utils.py +3 -10
  57. sqlspec/{statement/builder → builder}/_select.py +11 -56
  58. sqlspec/{statement/builder → builder}/_update.py +12 -18
  59. sqlspec/{statement/builder → builder}/mixins/__init__.py +10 -14
  60. sqlspec/{statement/builder → builder}/mixins/_cte_and_set_ops.py +48 -59
  61. sqlspec/{statement/builder → builder}/mixins/_insert_operations.py +22 -16
  62. sqlspec/{statement/builder → builder}/mixins/_join_operations.py +1 -3
  63. sqlspec/{statement/builder → builder}/mixins/_merge_operations.py +3 -5
  64. sqlspec/{statement/builder → builder}/mixins/_order_limit_operations.py +3 -3
  65. sqlspec/{statement/builder → builder}/mixins/_pivot_operations.py +4 -8
  66. sqlspec/{statement/builder → builder}/mixins/_select_operations.py +21 -36
  67. sqlspec/{statement/builder → builder}/mixins/_update_operations.py +3 -14
  68. sqlspec/{statement/builder → builder}/mixins/_where_clause.py +52 -79
  69. sqlspec/cli.py +4 -5
  70. sqlspec/config.py +180 -133
  71. sqlspec/core/__init__.py +63 -0
  72. sqlspec/core/cache.py +873 -0
  73. sqlspec/core/compiler.py +396 -0
  74. sqlspec/core/filters.py +828 -0
  75. sqlspec/core/hashing.py +310 -0
  76. sqlspec/core/parameters.py +1209 -0
  77. sqlspec/core/result.py +664 -0
  78. sqlspec/{statement → core}/splitter.py +321 -191
  79. sqlspec/core/statement.py +651 -0
  80. sqlspec/driver/__init__.py +7 -10
  81. sqlspec/driver/_async.py +387 -176
  82. sqlspec/driver/_common.py +527 -289
  83. sqlspec/driver/_sync.py +390 -172
  84. sqlspec/driver/mixins/__init__.py +2 -19
  85. sqlspec/driver/mixins/_result_tools.py +168 -0
  86. sqlspec/driver/mixins/_sql_translator.py +6 -3
  87. sqlspec/exceptions.py +5 -252
  88. sqlspec/extensions/aiosql/adapter.py +93 -96
  89. sqlspec/extensions/litestar/config.py +0 -1
  90. sqlspec/extensions/litestar/handlers.py +15 -26
  91. sqlspec/extensions/litestar/plugin.py +16 -14
  92. sqlspec/extensions/litestar/providers.py +17 -52
  93. sqlspec/loader.py +424 -105
  94. sqlspec/migrations/__init__.py +12 -0
  95. sqlspec/migrations/base.py +92 -68
  96. sqlspec/migrations/commands.py +24 -106
  97. sqlspec/migrations/loaders.py +402 -0
  98. sqlspec/migrations/runner.py +49 -51
  99. sqlspec/migrations/tracker.py +31 -44
  100. sqlspec/migrations/utils.py +64 -24
  101. sqlspec/protocols.py +7 -183
  102. sqlspec/storage/__init__.py +1 -1
  103. sqlspec/storage/backends/base.py +37 -40
  104. sqlspec/storage/backends/fsspec.py +136 -112
  105. sqlspec/storage/backends/obstore.py +138 -160
  106. sqlspec/storage/capabilities.py +5 -4
  107. sqlspec/storage/registry.py +57 -106
  108. sqlspec/typing.py +136 -115
  109. sqlspec/utils/__init__.py +2 -3
  110. sqlspec/utils/correlation.py +0 -3
  111. sqlspec/utils/deprecation.py +6 -6
  112. sqlspec/utils/fixtures.py +6 -6
  113. sqlspec/utils/logging.py +0 -2
  114. sqlspec/utils/module_loader.py +7 -12
  115. sqlspec/utils/singleton.py +0 -1
  116. sqlspec/utils/sync_tools.py +16 -37
  117. sqlspec/utils/text.py +12 -51
  118. sqlspec/utils/type_guards.py +443 -232
  119. {sqlspec-0.14.1.dist-info → sqlspec-0.15.0.dist-info}/METADATA +7 -2
  120. sqlspec-0.15.0.dist-info/RECORD +134 -0
  121. sqlspec/adapters/adbc/transformers.py +0 -108
  122. sqlspec/driver/connection.py +0 -207
  123. sqlspec/driver/mixins/_cache.py +0 -114
  124. sqlspec/driver/mixins/_csv_writer.py +0 -91
  125. sqlspec/driver/mixins/_pipeline.py +0 -508
  126. sqlspec/driver/mixins/_query_tools.py +0 -796
  127. sqlspec/driver/mixins/_result_utils.py +0 -138
  128. sqlspec/driver/mixins/_storage.py +0 -912
  129. sqlspec/driver/mixins/_type_coercion.py +0 -128
  130. sqlspec/driver/parameters.py +0 -138
  131. sqlspec/statement/__init__.py +0 -21
  132. sqlspec/statement/builder/_merge.py +0 -95
  133. sqlspec/statement/cache.py +0 -50
  134. sqlspec/statement/filters.py +0 -625
  135. sqlspec/statement/parameters.py +0 -956
  136. sqlspec/statement/pipelines/__init__.py +0 -210
  137. sqlspec/statement/pipelines/analyzers/__init__.py +0 -9
  138. sqlspec/statement/pipelines/analyzers/_analyzer.py +0 -646
  139. sqlspec/statement/pipelines/context.py +0 -109
  140. sqlspec/statement/pipelines/transformers/__init__.py +0 -7
  141. sqlspec/statement/pipelines/transformers/_expression_simplifier.py +0 -88
  142. sqlspec/statement/pipelines/transformers/_literal_parameterizer.py +0 -1247
  143. sqlspec/statement/pipelines/transformers/_remove_comments_and_hints.py +0 -76
  144. sqlspec/statement/pipelines/validators/__init__.py +0 -23
  145. sqlspec/statement/pipelines/validators/_dml_safety.py +0 -290
  146. sqlspec/statement/pipelines/validators/_parameter_style.py +0 -370
  147. sqlspec/statement/pipelines/validators/_performance.py +0 -714
  148. sqlspec/statement/pipelines/validators/_security.py +0 -967
  149. sqlspec/statement/result.py +0 -435
  150. sqlspec/statement/sql.py +0 -1774
  151. sqlspec/utils/cached_property.py +0 -25
  152. sqlspec/utils/statement_hashing.py +0 -203
  153. sqlspec-0.14.1.dist-info/RECORD +0 -145
  154. /sqlspec/{statement/builder → builder}/mixins/_delete_operations.py +0 -0
  155. {sqlspec-0.14.1.dist-info → sqlspec-0.15.0.dist-info}/WHEEL +0 -0
  156. {sqlspec-0.14.1.dist-info → sqlspec-0.15.0.dist-info}/entry_points.txt +0 -0
  157. {sqlspec-0.14.1.dist-info → sqlspec-0.15.0.dist-info}/licenses/LICENSE +0 -0
  158. {sqlspec-0.14.1.dist-info → sqlspec-0.15.0.dist-info}/licenses/NOTICE +0 -0
@@ -1,4 +1,18 @@
1
- from sqlspec.adapters.bigquery.config import CONNECTION_FIELDS, BigQueryConfig
2
- from sqlspec.adapters.bigquery.driver import BigQueryConnection, BigQueryDriver
1
+ from sqlspec.adapters.bigquery._types import BigQueryConnection
2
+ from sqlspec.adapters.bigquery.config import BigQueryConfig, BigQueryConnectionParams
3
+ from sqlspec.adapters.bigquery.driver import (
4
+ BigQueryCursor,
5
+ BigQueryDriver,
6
+ BigQueryExceptionHandler,
7
+ bigquery_statement_config,
8
+ )
3
9
 
4
- __all__ = ("CONNECTION_FIELDS", "BigQueryConfig", "BigQueryConnection", "BigQueryDriver")
10
+ __all__ = (
11
+ "BigQueryConfig",
12
+ "BigQueryConnection",
13
+ "BigQueryConnectionParams",
14
+ "BigQueryCursor",
15
+ "BigQueryDriver",
16
+ "BigQueryExceptionHandler",
17
+ "bigquery_statement_config",
18
+ )
@@ -0,0 +1,12 @@
1
+ from typing import TYPE_CHECKING
2
+
3
+ from google.cloud.bigquery import Client
4
+
5
+ if TYPE_CHECKING:
6
+ from typing_extensions import TypeAlias
7
+
8
+ BigQueryConnection: TypeAlias = Client
9
+ else:
10
+ BigQueryConnection = Client
11
+
12
+ __all__ = ("BigQueryConnection",)
@@ -2,59 +2,81 @@
2
2
 
3
3
  import contextlib
4
4
  import logging
5
- from typing import TYPE_CHECKING, Any, Callable, ClassVar, Optional
5
+ from typing import TYPE_CHECKING, Any, Callable, ClassVar, Optional, TypedDict, Union
6
6
 
7
7
  from google.cloud.bigquery import LoadJobConfig, QueryJobConfig
8
+ from typing_extensions import NotRequired
8
9
 
9
- from sqlspec.adapters.bigquery.driver import BigQueryConnection, BigQueryDriver
10
+ from sqlspec.adapters.bigquery._types import BigQueryConnection
11
+ from sqlspec.adapters.bigquery.driver import BigQueryCursor, BigQueryDriver, bigquery_statement_config
10
12
  from sqlspec.config import NoPoolSyncConfig
11
13
  from sqlspec.exceptions import ImproperConfigurationError
12
- from sqlspec.statement.sql import SQLConfig
13
- from sqlspec.typing import DictRow, Empty
14
+ from sqlspec.typing import Empty
14
15
 
15
16
  if TYPE_CHECKING:
16
17
  from collections.abc import Generator
17
- from contextlib import AbstractContextManager
18
18
 
19
19
  from google.api_core.client_info import ClientInfo
20
20
  from google.api_core.client_options import ClientOptions
21
21
  from google.auth.credentials import Credentials
22
22
 
23
+ from sqlspec.core.statement import StatementConfig
24
+
25
+
23
26
  logger = logging.getLogger(__name__)
24
27
 
25
- CONNECTION_FIELDS = frozenset(
26
- {
27
- "project",
28
- "location",
29
- "credentials",
30
- "dataset_id",
31
- "credentials_path",
32
- "client_options",
33
- "client_info",
34
- "default_query_job_config",
35
- "default_load_job_config",
36
- "use_query_cache",
37
- "maximum_bytes_billed",
38
- "enable_bigquery_ml",
39
- "enable_gemini_integration",
40
- "query_timeout_ms",
41
- "job_timeout_ms",
42
- "reservation_id",
43
- "edition",
44
- "enable_cross_cloud",
45
- "enable_bigquery_omni",
46
- "use_avro_logical_types",
47
- "parquet_enable_list_inference",
48
- "enable_column_level_security",
49
- "enable_row_level_security",
50
- "enable_dataframes",
51
- "dataframes_backend",
52
- "enable_continuous_queries",
53
- "enable_vector_search",
54
- }
55
- )
56
-
57
- __all__ = ("CONNECTION_FIELDS", "BigQueryConfig")
28
+
29
+ class BigQueryConnectionParams(TypedDict, total=False):
30
+ """Standard BigQuery connection parameters.
31
+
32
+ Includes both official BigQuery client parameters and BigQuery-specific configuration options.
33
+ """
34
+
35
+ # Official BigQuery client constructor parameters
36
+ project: NotRequired[str]
37
+ location: NotRequired[str]
38
+ credentials: NotRequired["Credentials"]
39
+ client_options: NotRequired["ClientOptions"]
40
+ client_info: NotRequired["ClientInfo"]
41
+
42
+ # BigQuery-specific configuration options
43
+ default_query_job_config: NotRequired[QueryJobConfig]
44
+ default_load_job_config: NotRequired[LoadJobConfig]
45
+ dataset_id: NotRequired[str]
46
+ credentials_path: NotRequired[str]
47
+ use_query_cache: NotRequired[bool]
48
+ maximum_bytes_billed: NotRequired[int]
49
+ enable_bigquery_ml: NotRequired[bool]
50
+ enable_gemini_integration: NotRequired[bool]
51
+ query_timeout_ms: NotRequired[int]
52
+ job_timeout_ms: NotRequired[int]
53
+ reservation_id: NotRequired[str]
54
+ edition: NotRequired[str]
55
+ enable_cross_cloud: NotRequired[bool]
56
+ enable_bigquery_omni: NotRequired[bool]
57
+ use_avro_logical_types: NotRequired[bool]
58
+ parquet_enable_list_inference: NotRequired[bool]
59
+ enable_column_level_security: NotRequired[bool]
60
+ enable_row_level_security: NotRequired[bool]
61
+ enable_dataframes: NotRequired[bool]
62
+ dataframes_backend: NotRequired[str]
63
+ enable_continuous_queries: NotRequired[bool]
64
+ enable_vector_search: NotRequired[bool]
65
+ extra: NotRequired[dict[str, Any]]
66
+
67
+
68
+ class BigQueryDriverFeatures(TypedDict, total=False):
69
+ """BigQuery driver-specific features configuration.
70
+
71
+ Only non-standard BigQuery client parameters that are SQLSpec-specific extensions.
72
+ """
73
+
74
+ on_job_start: NotRequired["Callable[[str], None]"]
75
+ on_job_complete: NotRequired["Callable[[str, Any], None]"]
76
+ on_connection_create: NotRequired["Callable[[Any], None]"]
77
+
78
+
79
+ __all__ = ("BigQueryConfig", "BigQueryConnectionParams", "BigQueryDriverFeatures")
58
80
 
59
81
 
60
82
  class BigQueryConfig(NoPoolSyncConfig[BigQueryConnection, BigQueryDriver]):
@@ -63,229 +85,120 @@ class BigQueryConfig(NoPoolSyncConfig[BigQueryConnection, BigQueryDriver]):
63
85
  BigQuery is Google Cloud's serverless, highly scalable data warehouse with
64
86
  advanced analytics, machine learning, and AI capabilities. This configuration
65
87
  supports all BigQuery features including:
66
-
67
- - Gemini in BigQuery for AI-powered analytics
68
- - BigQuery ML for machine learning workflows
69
- - BigQuery DataFrames for Python-based analytics
70
- - Multi-modal data analysis (text, images, video, audio)
71
- - Cross-cloud data access (AWS S3, Azure Blob Storage)
72
- - Vector search and embeddings
73
- - Continuous queries for real-time processing
74
- - Advanced security and governance features
75
- - Parquet and Arrow format optimization
76
88
  """
77
89
 
78
- is_async: ClassVar[bool] = False
79
- supports_connection_pooling: ClassVar[bool] = False
80
-
81
- driver_type: type[BigQueryDriver] = BigQueryDriver
82
- connection_type: type[BigQueryConnection] = BigQueryConnection
83
-
84
- # Parameter style support information
85
- supported_parameter_styles: ClassVar[tuple[str, ...]] = ("named_at",)
86
- """BigQuery only supports @name (named_at) parameter style."""
87
-
88
- default_parameter_style: ClassVar[str] = "named_at"
89
- """BigQuery's native parameter style is @name (named_at)."""
90
+ driver_type: ClassVar[type[BigQueryDriver]] = BigQueryDriver
91
+ connection_type: "ClassVar[type[BigQueryConnection]]" = BigQueryConnection
90
92
 
91
93
  def __init__(
92
94
  self,
93
- statement_config: Optional[SQLConfig] = None,
94
- default_row_type: type[DictRow] = DictRow,
95
- # Core connection parameters
96
- project: Optional[str] = None,
97
- location: Optional[str] = None,
98
- credentials: Optional["Credentials"] = None,
99
- dataset_id: Optional[str] = None,
100
- credentials_path: Optional[str] = None,
101
- # Client configuration
102
- client_options: Optional["ClientOptions"] = None,
103
- client_info: Optional["ClientInfo"] = None,
104
- # Job configuration
105
- default_query_job_config: Optional["QueryJobConfig"] = None,
106
- default_load_job_config: Optional["LoadJobConfig"] = None,
107
- # Advanced BigQuery features
108
- use_query_cache: Optional[bool] = None,
109
- maximum_bytes_billed: Optional[int] = None,
110
- # BigQuery ML and AI configuration
111
- enable_bigquery_ml: Optional[bool] = None,
112
- enable_gemini_integration: Optional[bool] = None,
113
- # Performance and scaling options
114
- query_timeout_ms: Optional[int] = None,
115
- job_timeout_ms: Optional[int] = None,
116
- # BigQuery editions and reservations
117
- reservation_id: Optional[str] = None,
118
- edition: Optional[str] = None,
119
- # Cross-cloud and external data options
120
- enable_cross_cloud: Optional[bool] = None,
121
- enable_bigquery_omni: Optional[bool] = None,
122
- # Storage and format options
123
- use_avro_logical_types: Optional[bool] = None,
124
- parquet_enable_list_inference: Optional[bool] = None,
125
- # Security and governance
126
- enable_column_level_security: Optional[bool] = None,
127
- enable_row_level_security: Optional[bool] = None,
128
- # DataFrames and Python integration
129
- enable_dataframes: Optional[bool] = None,
130
- dataframes_backend: Optional[str] = None,
131
- # Continuous queries and real-time processing
132
- enable_continuous_queries: Optional[bool] = None,
133
- # Vector search and embeddings
134
- enable_vector_search: Optional[bool] = None,
135
- # Callback functions
136
- on_connection_create: Optional[Callable[[BigQueryConnection], None]] = None,
137
- on_job_start: Optional[Callable[[str], None]] = None,
138
- on_job_complete: Optional[Callable[[str, Any], None]] = None,
139
- **kwargs: Any,
95
+ *,
96
+ connection_instance: "Optional[BigQueryConnection]" = None,
97
+ connection_config: "Optional[Union[BigQueryConnectionParams, dict[str, Any]]]" = None,
98
+ migration_config: Optional[dict[str, Any]] = None,
99
+ statement_config: "Optional[StatementConfig]" = None,
100
+ driver_features: "Optional[Union[BigQueryDriverFeatures, dict[str, Any]]]" = None,
140
101
  ) -> None:
141
102
  """Initialize BigQuery configuration with comprehensive feature support.
142
103
 
143
104
  Args:
144
- statement_config: Default SQL statement configuration
145
- default_row_type: Default row type for results
146
- project: Google Cloud project ID
147
- location: Default geographic location for jobs and datasets
148
- credentials: Credentials to use for authentication
149
- dataset_id: Default dataset ID to use if not specified in queries
150
- credentials_path: Path to Google Cloud service account key file (JSON)
151
- client_options: Client options used to set user options on the client
152
- client_info: Client info used to send a user-agent string along with API requests
153
- default_query_job_config: Default QueryJobConfig settings for query operations
154
- default_load_job_config: Default LoadJobConfig settings for data loading operations
155
- use_query_cache: Whether to use query cache for faster repeated queries
156
- maximum_bytes_billed: Maximum bytes that can be billed for queries to prevent runaway costs
157
- enable_bigquery_ml: Enable BigQuery ML capabilities for machine learning workflows
158
- enable_gemini_integration: Enable Gemini in BigQuery for AI-powered analytics and code assistance
159
- query_timeout_ms: Query timeout in milliseconds
160
- job_timeout_ms: Job timeout in milliseconds
161
- reservation_id: Reservation ID for slot allocation and workload management
162
- edition: BigQuery edition (Standard, Enterprise, Enterprise Plus)
163
- enable_cross_cloud: Enable cross-cloud data access (AWS S3, Azure Blob Storage)
164
- enable_bigquery_omni: Enable BigQuery Omni for multi-cloud analytics
165
- use_avro_logical_types: Use Avro logical types for better type preservation
166
- parquet_enable_list_inference: Enable automatic list inference for Parquet data
167
- enable_column_level_security: Enable column-level access controls and data masking
168
- enable_row_level_security: Enable row-level security policies
169
- enable_dataframes: Enable BigQuery DataFrames for Python-based analytics
170
- dataframes_backend: Backend for BigQuery DataFrames (e.g., 'bigframes')
171
- enable_continuous_queries: Enable continuous queries for real-time data processing
172
- enable_vector_search: Enable vector search capabilities for AI/ML workloads
173
- on_connection_create: Callback executed when connection is created
174
- on_job_start: Callback executed when a BigQuery job starts
175
- on_job_complete: Callback executed when a BigQuery job completes
176
- **kwargs: Additional parameters (stored in extras)
105
+ connection_config: Standard connection configuration parameters
106
+ connection_instance: Existing connection instance to use
107
+ migration_config: Migration configuration
108
+ statement_config: Statement configuration override
109
+ driver_features: BigQuery-specific driver features and configurations
177
110
 
178
111
  Example:
179
112
  >>> # Basic BigQuery connection
180
- >>> config = BigQueryConfig(project="my-project", location="US")
113
+ >>> config = BigQueryConfig(
114
+ ... connection_config={
115
+ ... "project": "my-project",
116
+ ... "location": "US",
117
+ ... }
118
+ ... )
181
119
 
182
120
  >>> # Advanced configuration with ML and AI features
183
121
  >>> config = BigQueryConfig(
184
- ... project="my-project",
185
- ... location="US",
186
- ... enable_bigquery_ml=True,
187
- ... enable_gemini_integration=True,
188
- ... enable_dataframes=True,
189
- ... enable_vector_search=True,
190
- ... maximum_bytes_billed=1000000000, # 1GB limit
122
+ ... connection_config={
123
+ ... "project": "my-project",
124
+ ... "location": "US",
125
+ ... "enable_bigquery_ml": True,
126
+ ... "enable_gemini_integration": True,
127
+ ... "enable_dataframes": True,
128
+ ... "enable_vector_search": True,
129
+ ... "maximum_bytes_billed": 1000000000, # 1GB limit
130
+ ... }
191
131
  ... )
192
132
 
193
133
  >>> # Enterprise configuration with reservations
194
134
  >>> config = BigQueryConfig(
195
- ... project="my-project",
196
- ... location="US",
197
- ... edition="Enterprise Plus",
198
- ... reservation_id="my-reservation",
199
- ... enable_continuous_queries=True,
200
- ... enable_cross_cloud=True,
135
+ ... connection_config={
136
+ ... "project": "my-project",
137
+ ... "location": "US",
138
+ ... "edition": "Enterprise Plus",
139
+ ... "reservation_id": "my-reservation",
140
+ ... "enable_continuous_queries": True,
141
+ ... "enable_cross_cloud": True,
142
+ ... }
201
143
  ... )
202
144
  """
203
- # Store connection parameters as instance attributes
204
- self.project = project
205
- self.location = location
206
- self.credentials = credentials
207
- self.dataset_id = dataset_id
208
- self.credentials_path = credentials_path
209
- self.client_options = client_options
210
- self.client_info = client_info
211
- self.default_query_job_config = default_query_job_config
212
- self.default_load_job_config = default_load_job_config
213
- self.use_query_cache = use_query_cache
214
- self.maximum_bytes_billed = maximum_bytes_billed
215
- self.enable_bigquery_ml = enable_bigquery_ml
216
- self.enable_gemini_integration = enable_gemini_integration
217
- self.query_timeout_ms = query_timeout_ms
218
- self.job_timeout_ms = job_timeout_ms
219
- self.reservation_id = reservation_id
220
- self.edition = edition
221
- self.enable_cross_cloud = enable_cross_cloud
222
- self.enable_bigquery_omni = enable_bigquery_omni
223
- self.use_avro_logical_types = use_avro_logical_types
224
- self.parquet_enable_list_inference = parquet_enable_list_inference
225
- self.enable_column_level_security = enable_column_level_security
226
- self.enable_row_level_security = enable_row_level_security
227
- self.enable_dataframes = enable_dataframes
228
- self.dataframes_backend = dataframes_backend
229
- self.enable_continuous_queries = enable_continuous_queries
230
- self.enable_vector_search = enable_vector_search
231
-
232
- self.extras = kwargs or {}
233
-
234
- # Store other config
235
- self.statement_config = statement_config or SQLConfig(dialect="bigquery")
236
- self.default_row_type = default_row_type
237
- self.on_connection_create = on_connection_create
238
- self.on_job_start = on_job_start
239
- self.on_job_complete = on_job_complete
240
-
241
- if self.default_query_job_config is None:
145
+
146
+ # Store connection instance
147
+ self._connection_instance = connection_instance
148
+
149
+ # Setup configuration following DuckDB pattern
150
+ self.connection_config: dict[str, Any] = dict(connection_config) if connection_config else {}
151
+ if "extra" in self.connection_config:
152
+ extras = self.connection_config.pop("extra")
153
+ self.connection_config.update(extras)
154
+
155
+ # Setup driver features
156
+ self.driver_features: dict[str, Any] = dict(driver_features) if driver_features else {}
157
+
158
+ # Setup default job config if not provided
159
+ if "default_query_job_config" not in self.connection_config:
242
160
  self._setup_default_job_config()
243
161
 
244
- # Store connection instance for reuse (BigQuery doesn't support traditional pooling)
245
- self._connection_instance: Optional[BigQueryConnection] = None
162
+ if statement_config is None:
163
+ statement_config = bigquery_statement_config
246
164
 
247
- super().__init__()
165
+ super().__init__(
166
+ connection_config=self.connection_config,
167
+ migration_config=migration_config,
168
+ statement_config=statement_config,
169
+ driver_features=self.driver_features,
170
+ )
248
171
 
249
172
  def _setup_default_job_config(self) -> None:
250
- """Set up default job configuration based on connection settings."""
173
+ """Set up default job configuration based on connection config."""
174
+ # Check if already provided in connection_config
175
+ if self.connection_config.get("default_query_job_config") is not None:
176
+ return
177
+
251
178
  job_config = QueryJobConfig()
252
179
 
253
- if self.dataset_id and self.project and "." not in self.dataset_id:
254
- job_config.default_dataset = f"{self.project}.{self.dataset_id}"
255
- if self.use_query_cache is not None:
256
- job_config.use_query_cache = self.use_query_cache
180
+ dataset_id = self.connection_config.get("dataset_id")
181
+ project = self.connection_config.get("project")
182
+ if dataset_id and project and "." not in dataset_id:
183
+ job_config.default_dataset = f"{project}.{dataset_id}"
184
+
185
+ use_query_cache = self.connection_config.get("use_query_cache")
186
+ if use_query_cache is not None:
187
+ job_config.use_query_cache = use_query_cache
257
188
  else:
258
189
  job_config.use_query_cache = True # Default to True
259
190
 
260
191
  # Configure cost controls
261
- if self.maximum_bytes_billed is not None:
262
- job_config.maximum_bytes_billed = self.maximum_bytes_billed
192
+ maximum_bytes_billed = self.connection_config.get("maximum_bytes_billed")
193
+ if maximum_bytes_billed is not None:
194
+ job_config.maximum_bytes_billed = maximum_bytes_billed
263
195
 
264
196
  # Configure timeouts
265
- if self.query_timeout_ms is not None:
266
- job_config.job_timeout_ms = self.query_timeout_ms
267
-
268
- self.default_query_job_config = job_config
269
-
270
- @property
271
- def connection_config_dict(self) -> dict[str, Any]:
272
- """Return the connection configuration as a dict for BigQuery Client constructor.
197
+ query_timeout_ms = self.connection_config.get("query_timeout_ms")
198
+ if query_timeout_ms is not None:
199
+ job_config.job_timeout_ms = query_timeout_ms
273
200
 
274
- Filters out BigQuery-specific enhancement flags and formats parameters
275
- appropriately for the google.cloud.bigquery.Client constructor.
276
-
277
- Returns:
278
- Configuration dict for BigQuery Client constructor.
279
- """
280
- client_fields = {"project", "location", "credentials", "client_options", "client_info"}
281
- config = {
282
- field: getattr(self, field)
283
- for field in client_fields
284
- if getattr(self, field, None) is not None and getattr(self, field) is not Empty
285
- }
286
- config.update(self.extras)
287
-
288
- return config
201
+ self.connection_config["default_query_job_config"] = job_config
289
202
 
290
203
  def create_connection(self) -> BigQueryConnection:
291
204
  """Create and return a new BigQuery Client instance.
@@ -301,21 +214,39 @@ class BigQueryConfig(NoPoolSyncConfig[BigQueryConnection, BigQueryDriver]):
301
214
  return self._connection_instance
302
215
 
303
216
  try:
304
- config_dict = self.connection_config_dict
305
-
217
+ # Filter out extra fields and keep only official BigQuery client constructor fields
218
+ client_fields = {"project", "location", "credentials", "client_options", "client_info"}
219
+ config_dict: dict[str, Any] = {
220
+ field: value
221
+ for field, value in self.connection_config.items()
222
+ if field in client_fields and value is not None and value is not Empty
223
+ }
306
224
  connection = self.connection_type(**config_dict)
307
- if self.on_connection_create:
308
- self.on_connection_create(connection)
225
+
226
+ # Store BigQuery-specific config in driver_features for driver access
227
+ default_query_job_config = self.connection_config.get("default_query_job_config")
228
+ if default_query_job_config is not None:
229
+ self.driver_features["default_query_job_config"] = default_query_job_config
230
+
231
+ default_load_job_config = self.connection_config.get("default_load_job_config")
232
+ if default_load_job_config is not None:
233
+ self.driver_features["default_load_job_config"] = default_load_job_config
234
+
235
+ # Call connection create callback from driver features
236
+ on_connection_create = self.driver_features.get("on_connection_create")
237
+ if on_connection_create:
238
+ on_connection_create(connection)
309
239
 
310
240
  self._connection_instance = connection
311
241
 
312
242
  except Exception as e:
313
- msg = f"Could not configure BigQuery connection for project '{self.project or 'Unknown'}'. Error: {e}"
243
+ project = self.connection_config.get("project", "Unknown")
244
+ msg = f"Could not configure BigQuery connection for project '{project}'. Error: {e}"
314
245
  raise ImproperConfigurationError(msg) from e
315
246
  return connection
316
247
 
317
248
  @contextlib.contextmanager
318
- def provide_connection(self, *args: Any, **kwargs: Any) -> "Generator[BigQueryConnection, None, None]":
249
+ def provide_connection(self, *_args: Any, **_kwargs: Any) -> "Generator[BigQueryConnection, None, None]":
319
250
  """Provide a BigQuery client within a context manager.
320
251
 
321
252
  Args:
@@ -328,38 +259,40 @@ class BigQueryConfig(NoPoolSyncConfig[BigQueryConnection, BigQueryDriver]):
328
259
  connection = self.create_connection()
329
260
  yield connection
330
261
 
331
- def provide_session(self, *args: Any, **kwargs: Any) -> "AbstractContextManager[BigQueryDriver]":
262
+ @contextlib.contextmanager
263
+ def provide_session(
264
+ self, *_args: Any, statement_config: "Optional[StatementConfig]" = None, **_kwargs: Any
265
+ ) -> "Generator[BigQueryDriver, None, None]":
332
266
  """Provide a BigQuery driver session context manager.
333
267
 
334
268
  Args:
335
269
  *args: Additional arguments.
270
+ statement_config: Optional statement configuration override.
336
271
  **kwargs: Additional keyword arguments.
337
272
 
338
- Returns:
273
+ Yields:
339
274
  A context manager that yields a BigQueryDriver instance.
340
275
  """
341
276
 
342
- @contextlib.contextmanager
343
- def session_manager() -> "Generator[BigQueryDriver, None, None]":
344
- with self.provide_connection(*args, **kwargs) as connection:
345
- statement_config = self.statement_config
346
- # Inject parameter style info if not already set
347
- if statement_config.allowed_parameter_styles is None:
348
- from dataclasses import replace
349
-
350
- statement_config = replace(
351
- statement_config,
352
- allowed_parameter_styles=self.supported_parameter_styles,
353
- default_parameter_style=self.default_parameter_style,
354
- )
355
- driver = self.driver_type(
356
- connection=connection,
357
- config=statement_config,
358
- default_row_type=self.default_row_type,
359
- default_query_job_config=self.default_query_job_config,
360
- on_job_start=self.on_job_start,
361
- on_job_complete=self.on_job_complete,
362
- )
363
- yield driver
364
-
365
- return session_manager()
277
+ with self.provide_connection(*_args, **_kwargs) as connection:
278
+ # Use shared config or user-provided config or instance default
279
+ final_statement_config = statement_config or self.statement_config
280
+
281
+ driver = self.driver_type(
282
+ connection=connection, statement_config=final_statement_config, driver_features=self.driver_features
283
+ )
284
+ yield driver
285
+
286
+ def get_signature_namespace(self) -> "dict[str, type[Any]]":
287
+ """Get the signature namespace for BigQuery types.
288
+
289
+ This provides all BigQuery-specific types that Litestar needs to recognize
290
+ to avoid serialization attempts.
291
+
292
+ Returns:
293
+ Dictionary mapping type names to types.
294
+ """
295
+
296
+ namespace = super().get_signature_namespace()
297
+ namespace.update({"BigQueryConnection": BigQueryConnection, "BigQueryCursor": BigQueryCursor})
298
+ return namespace