sqlspec 0.9.0__py3-none-any.whl → 0.10.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 (47) hide show
  1. sqlspec/__init__.py +2 -1
  2. sqlspec/adapters/adbc/__init__.py +2 -1
  3. sqlspec/adapters/adbc/config.py +7 -13
  4. sqlspec/adapters/adbc/driver.py +160 -21
  5. sqlspec/adapters/aiosqlite/__init__.py +2 -1
  6. sqlspec/adapters/aiosqlite/config.py +10 -12
  7. sqlspec/adapters/aiosqlite/driver.py +160 -22
  8. sqlspec/adapters/asyncmy/__init__.py +2 -1
  9. sqlspec/adapters/asyncmy/driver.py +158 -22
  10. sqlspec/adapters/asyncpg/config.py +1 -3
  11. sqlspec/adapters/asyncpg/driver.py +143 -5
  12. sqlspec/adapters/bigquery/__init__.py +4 -0
  13. sqlspec/adapters/bigquery/config/__init__.py +3 -0
  14. sqlspec/adapters/bigquery/config/_common.py +40 -0
  15. sqlspec/adapters/bigquery/config/_sync.py +87 -0
  16. sqlspec/adapters/bigquery/driver.py +701 -0
  17. sqlspec/adapters/duckdb/__init__.py +2 -1
  18. sqlspec/adapters/duckdb/config.py +17 -18
  19. sqlspec/adapters/duckdb/driver.py +165 -27
  20. sqlspec/adapters/oracledb/__init__.py +8 -1
  21. sqlspec/adapters/oracledb/config/_asyncio.py +7 -8
  22. sqlspec/adapters/oracledb/config/_sync.py +6 -7
  23. sqlspec/adapters/oracledb/driver.py +311 -42
  24. sqlspec/adapters/psqlpy/__init__.py +9 -0
  25. sqlspec/adapters/psqlpy/config.py +11 -19
  26. sqlspec/adapters/psqlpy/driver.py +171 -19
  27. sqlspec/adapters/psycopg/__init__.py +8 -1
  28. sqlspec/adapters/psycopg/config/__init__.py +10 -0
  29. sqlspec/adapters/psycopg/config/_async.py +6 -7
  30. sqlspec/adapters/psycopg/config/_sync.py +7 -8
  31. sqlspec/adapters/psycopg/driver.py +344 -86
  32. sqlspec/adapters/sqlite/__init__.py +2 -1
  33. sqlspec/adapters/sqlite/config.py +12 -11
  34. sqlspec/adapters/sqlite/driver.py +160 -51
  35. sqlspec/base.py +402 -63
  36. sqlspec/exceptions.py +9 -0
  37. sqlspec/extensions/litestar/config.py +3 -11
  38. sqlspec/extensions/litestar/handlers.py +2 -1
  39. sqlspec/extensions/litestar/plugin.py +6 -2
  40. sqlspec/mixins.py +156 -0
  41. sqlspec/typing.py +19 -1
  42. {sqlspec-0.9.0.dist-info → sqlspec-0.10.0.dist-info}/METADATA +147 -3
  43. sqlspec-0.10.0.dist-info/RECORD +67 -0
  44. sqlspec-0.9.0.dist-info/RECORD +0 -61
  45. {sqlspec-0.9.0.dist-info → sqlspec-0.10.0.dist-info}/WHEEL +0 -0
  46. {sqlspec-0.9.0.dist-info → sqlspec-0.10.0.dist-info}/licenses/LICENSE +0 -0
  47. {sqlspec-0.9.0.dist-info → sqlspec-0.10.0.dist-info}/licenses/NOTICE +0 -0
@@ -1,9 +1,9 @@
1
+ import sqlite3
1
2
  from contextlib import contextmanager
2
3
  from dataclasses import dataclass, field
3
- from sqlite3 import Connection
4
4
  from typing import TYPE_CHECKING, Any, Literal, Optional, Union
5
5
 
6
- from sqlspec.adapters.sqlite.driver import SqliteDriver
6
+ from sqlspec.adapters.sqlite.driver import SqliteConnection, SqliteDriver
7
7
  from sqlspec.base import NoPoolSyncConfig
8
8
  from sqlspec.exceptions import ImproperConfigurationError
9
9
  from sqlspec.typing import Empty, EmptyType, dataclass_to_dict
@@ -16,7 +16,7 @@ __all__ = ("SqliteConfig",)
16
16
 
17
17
 
18
18
  @dataclass
19
- class SqliteConfig(NoPoolSyncConfig["Connection", "SqliteDriver"]):
19
+ class SqliteConfig(NoPoolSyncConfig["SqliteConnection", "SqliteDriver"]):
20
20
  """Configuration for SQLite database connections.
21
21
 
22
22
  This class provides configuration options for SQLite database connections, wrapping all parameters
@@ -40,7 +40,7 @@ class SqliteConfig(NoPoolSyncConfig["Connection", "SqliteDriver"]):
40
40
  check_same_thread: "Union[bool, EmptyType]" = Empty
41
41
  """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."""
42
42
 
43
- factory: "Union[type[Connection], EmptyType]" = Empty
43
+ factory: "Union[type[SqliteConnection], EmptyType]" = Empty
44
44
  """A custom Connection class factory. If given, must be a callable that returns a Connection instance."""
45
45
 
46
46
  cached_statements: "Union[int, EmptyType]" = Empty
@@ -50,7 +50,7 @@ class SqliteConfig(NoPoolSyncConfig["Connection", "SqliteDriver"]):
50
50
  """If set to True, database is interpreted as a URI with supported options."""
51
51
  driver_type: "type[SqliteDriver]" = field(init=False, default_factory=lambda: SqliteDriver)
52
52
  """Type of the driver object"""
53
- connection_type: "type[Connection]" = field(init=False, default_factory=lambda: Connection)
53
+ connection_type: "type[SqliteConnection]" = field(init=False, default_factory=lambda: SqliteConnection)
54
54
  """Type of the connection object"""
55
55
 
56
56
  @property
@@ -61,10 +61,13 @@ class SqliteConfig(NoPoolSyncConfig["Connection", "SqliteDriver"]):
61
61
  A string keyed dict of config kwargs for the sqlite3.connect() function.
62
62
  """
63
63
  return dataclass_to_dict(
64
- self, exclude_empty=True, convert_nested=False, exclude={"pool_instance", "driver_type", "connection_type"}
64
+ self,
65
+ exclude_empty=True,
66
+ convert_nested=False,
67
+ exclude={"pool_instance", "driver_type", "connection_type"},
65
68
  )
66
69
 
67
- def create_connection(self) -> "Connection":
70
+ def create_connection(self) -> "SqliteConnection":
68
71
  """Create and return a new database connection.
69
72
 
70
73
  Returns:
@@ -73,8 +76,6 @@ class SqliteConfig(NoPoolSyncConfig["Connection", "SqliteDriver"]):
73
76
  Raises:
74
77
  ImproperConfigurationError: If the connection could not be established.
75
78
  """
76
- import sqlite3
77
-
78
79
  try:
79
80
  return sqlite3.connect(**self.connection_config_dict) # type: ignore[no-any-return,unused-ignore]
80
81
  except Exception as e:
@@ -82,7 +83,7 @@ class SqliteConfig(NoPoolSyncConfig["Connection", "SqliteDriver"]):
82
83
  raise ImproperConfigurationError(msg) from e
83
84
 
84
85
  @contextmanager
85
- def provide_connection(self, *args: "Any", **kwargs: "Any") -> "Generator[Connection, None, None]":
86
+ def provide_connection(self, *args: "Any", **kwargs: "Any") -> "Generator[SqliteConnection, None, None]":
86
87
  """Create and provide a database connection.
87
88
 
88
89
  Yields:
@@ -100,7 +101,7 @@ class SqliteConfig(NoPoolSyncConfig["Connection", "SqliteDriver"]):
100
101
  """Create and provide a database connection.
101
102
 
102
103
  Yields:
103
- A DuckDB driver instance.
104
+ A SQLite driver instance.
104
105
 
105
106
 
106
107
  """
@@ -1,48 +1,78 @@
1
+ import sqlite3
1
2
  from contextlib import contextmanager
2
- from sqlite3 import Connection, Cursor
3
- from typing import TYPE_CHECKING, Any, Optional, Union, cast
3
+ from sqlite3 import Cursor
4
+ from typing import TYPE_CHECKING, Any, Optional, Union, cast, overload
4
5
 
5
- from sqlspec.base import SyncDriverAdapterProtocol, T
6
+ from sqlspec.base import SyncDriverAdapterProtocol
7
+ from sqlspec.mixins import SQLTranslatorMixin
6
8
 
7
9
  if TYPE_CHECKING:
8
- from collections.abc import Generator
10
+ from collections.abc import Generator, Sequence
9
11
 
10
- from sqlspec.typing import ModelDTOT, StatementParameterType
12
+ from sqlspec.typing import ModelDTOT, StatementParameterType, T
11
13
 
12
- __all__ = ("SqliteDriver",)
14
+ __all__ = ("SqliteConnection", "SqliteDriver")
13
15
 
16
+ SqliteConnection = sqlite3.Connection
14
17
 
15
- class SqliteDriver(SyncDriverAdapterProtocol["Connection"]):
18
+
19
+ class SqliteDriver(
20
+ SQLTranslatorMixin["SqliteConnection"],
21
+ SyncDriverAdapterProtocol["SqliteConnection"],
22
+ ):
16
23
  """SQLite Sync Driver Adapter."""
17
24
 
18
- connection: "Connection"
25
+ connection: "SqliteConnection"
19
26
  dialect: str = "sqlite"
20
27
 
21
- def __init__(self, connection: "Connection") -> None:
28
+ def __init__(self, connection: "SqliteConnection") -> None:
22
29
  self.connection = connection
23
30
 
24
31
  @staticmethod
25
- def _cursor(connection: "Connection", *args: Any, **kwargs: Any) -> Cursor:
32
+ def _cursor(connection: "SqliteConnection", *args: Any, **kwargs: Any) -> Cursor:
26
33
  return connection.cursor(*args, **kwargs) # type: ignore[no-any-return]
27
34
 
28
35
  @contextmanager
29
- def _with_cursor(self, connection: "Connection") -> "Generator[Cursor, None, None]":
36
+ def _with_cursor(self, connection: "SqliteConnection") -> "Generator[Cursor, None, None]":
30
37
  cursor = self._cursor(connection)
31
38
  try:
32
39
  yield cursor
33
40
  finally:
34
41
  cursor.close()
35
42
 
43
+ # --- Public API Methods --- #
44
+ @overload
45
+ def select(
46
+ self,
47
+ sql: str,
48
+ parameters: "Optional[StatementParameterType]" = None,
49
+ /,
50
+ *,
51
+ connection: "Optional[SqliteConnection]" = None,
52
+ schema_type: None = None,
53
+ **kwargs: Any,
54
+ ) -> "Sequence[dict[str, Any]]": ...
55
+ @overload
56
+ def select(
57
+ self,
58
+ sql: str,
59
+ parameters: "Optional[StatementParameterType]" = None,
60
+ /,
61
+ *,
62
+ connection: "Optional[SqliteConnection]" = None,
63
+ schema_type: "type[ModelDTOT]",
64
+ **kwargs: Any,
65
+ ) -> "Sequence[ModelDTOT]": ...
36
66
  def select(
37
67
  self,
38
68
  sql: str,
39
69
  parameters: Optional["StatementParameterType"] = None,
40
70
  /,
41
71
  *,
42
- connection: Optional["Connection"] = None,
72
+ connection: Optional["SqliteConnection"] = None,
43
73
  schema_type: "Optional[type[ModelDTOT]]" = None,
44
74
  **kwargs: Any,
45
- ) -> "list[Union[ModelDTOT, dict[str, Any]]]":
75
+ ) -> "Sequence[Union[ModelDTOT, dict[str, Any]]]":
46
76
  """Fetch data from the database.
47
77
 
48
78
  Returns:
@@ -63,13 +93,35 @@ class SqliteDriver(SyncDriverAdapterProtocol["Connection"]):
63
93
  return [cast("ModelDTOT", schema_type(**dict(zip(column_names, row)))) for row in results] # pyright: ignore[reportUnknownArgumentType]
64
94
  return [dict(zip(column_names, row)) for row in results] # pyright: ignore[reportUnknownArgumentType]
65
95
 
96
+ @overload
97
+ def select_one(
98
+ self,
99
+ sql: str,
100
+ parameters: "Optional[StatementParameterType]" = None,
101
+ /,
102
+ *,
103
+ connection: "Optional[SqliteConnection]" = None,
104
+ schema_type: None = None,
105
+ **kwargs: Any,
106
+ ) -> "dict[str, Any]": ...
107
+ @overload
108
+ def select_one(
109
+ self,
110
+ sql: str,
111
+ parameters: "Optional[StatementParameterType]" = None,
112
+ /,
113
+ *,
114
+ connection: "Optional[SqliteConnection]" = None,
115
+ schema_type: "type[ModelDTOT]",
116
+ **kwargs: Any,
117
+ ) -> "ModelDTOT": ...
66
118
  def select_one(
67
119
  self,
68
120
  sql: str,
69
121
  parameters: Optional["StatementParameterType"] = None,
70
122
  /,
71
123
  *,
72
- connection: Optional["Connection"] = None,
124
+ connection: Optional["SqliteConnection"] = None,
73
125
  schema_type: "Optional[type[ModelDTOT]]" = None,
74
126
  **kwargs: Any,
75
127
  ) -> "Union[ModelDTOT, dict[str, Any]]":
@@ -92,13 +144,35 @@ class SqliteDriver(SyncDriverAdapterProtocol["Connection"]):
92
144
  return dict(zip(column_names, result))
93
145
  return schema_type(**dict(zip(column_names, result))) # type: ignore[return-value]
94
146
 
147
+ @overload
148
+ def select_one_or_none(
149
+ self,
150
+ sql: str,
151
+ parameters: "Optional[StatementParameterType]" = None,
152
+ /,
153
+ *,
154
+ connection: "Optional[SqliteConnection]" = None,
155
+ schema_type: None = None,
156
+ **kwargs: Any,
157
+ ) -> "Optional[dict[str, Any]]": ...
158
+ @overload
159
+ def select_one_or_none(
160
+ self,
161
+ sql: str,
162
+ parameters: "Optional[StatementParameterType]" = None,
163
+ /,
164
+ *,
165
+ connection: "Optional[SqliteConnection]" = None,
166
+ schema_type: "type[ModelDTOT]",
167
+ **kwargs: Any,
168
+ ) -> "Optional[ModelDTOT]": ...
95
169
  def select_one_or_none(
96
170
  self,
97
171
  sql: str,
98
172
  parameters: Optional["StatementParameterType"] = None,
99
173
  /,
100
174
  *,
101
- connection: Optional["Connection"] = None,
175
+ connection: Optional["SqliteConnection"] = None,
102
176
  schema_type: "Optional[type[ModelDTOT]]" = None,
103
177
  **kwargs: Any,
104
178
  ) -> "Optional[Union[ModelDTOT, dict[str, Any]]]":
@@ -122,13 +196,35 @@ class SqliteDriver(SyncDriverAdapterProtocol["Connection"]):
122
196
  return dict(zip(column_names, result))
123
197
  return schema_type(**dict(zip(column_names, result))) # type: ignore[return-value]
124
198
 
199
+ @overload
200
+ def select_value(
201
+ self,
202
+ sql: str,
203
+ parameters: "Optional[StatementParameterType]" = None,
204
+ /,
205
+ *,
206
+ connection: "Optional[SqliteConnection]" = None,
207
+ schema_type: None = None,
208
+ **kwargs: Any,
209
+ ) -> "Any": ...
210
+ @overload
125
211
  def select_value(
126
212
  self,
127
213
  sql: str,
128
214
  parameters: "Optional[StatementParameterType]" = None,
129
215
  /,
130
216
  *,
131
- connection: "Optional[Connection]" = None,
217
+ connection: "Optional[SqliteConnection]" = None,
218
+ schema_type: "type[T]",
219
+ **kwargs: Any,
220
+ ) -> "T": ...
221
+ def select_value(
222
+ self,
223
+ sql: str,
224
+ parameters: "Optional[StatementParameterType]" = None,
225
+ /,
226
+ *,
227
+ connection: "Optional[SqliteConnection]" = None,
132
228
  schema_type: "Optional[type[T]]" = None,
133
229
  **kwargs: Any,
134
230
  ) -> "Union[T, Any]":
@@ -150,13 +246,35 @@ class SqliteDriver(SyncDriverAdapterProtocol["Connection"]):
150
246
  return result[0]
151
247
  return schema_type(result[0]) # type: ignore[call-arg]
152
248
 
249
+ @overload
250
+ def select_value_or_none(
251
+ self,
252
+ sql: str,
253
+ parameters: "Optional[StatementParameterType]" = None,
254
+ /,
255
+ *,
256
+ connection: "Optional[SqliteConnection]" = None,
257
+ schema_type: None = None,
258
+ **kwargs: Any,
259
+ ) -> "Optional[Any]": ...
260
+ @overload
261
+ def select_value_or_none(
262
+ self,
263
+ sql: str,
264
+ parameters: "Optional[StatementParameterType]" = None,
265
+ /,
266
+ *,
267
+ connection: "Optional[SqliteConnection]" = None,
268
+ schema_type: "type[T]",
269
+ **kwargs: Any,
270
+ ) -> "Optional[T]": ...
153
271
  def select_value_or_none(
154
272
  self,
155
273
  sql: str,
156
274
  parameters: "Optional[StatementParameterType]" = None,
157
275
  /,
158
276
  *,
159
- connection: "Optional[Connection]" = None,
277
+ connection: "Optional[SqliteConnection]" = None,
160
278
  schema_type: "Optional[type[T]]" = None,
161
279
  **kwargs: Any,
162
280
  ) -> "Optional[Union[T, Any]]":
@@ -185,7 +303,7 @@ class SqliteDriver(SyncDriverAdapterProtocol["Connection"]):
185
303
  parameters: Optional["StatementParameterType"] = None,
186
304
  /,
187
305
  *,
188
- connection: Optional["Connection"] = None,
306
+ connection: Optional["SqliteConnection"] = None,
189
307
  **kwargs: Any,
190
308
  ) -> int:
191
309
  """Insert, update, or delete data from the database.
@@ -203,13 +321,35 @@ class SqliteDriver(SyncDriverAdapterProtocol["Connection"]):
203
321
  cursor.execute(sql, parameters)
204
322
  return cursor.rowcount if hasattr(cursor, "rowcount") else -1
205
323
 
324
+ @overload
325
+ def insert_update_delete_returning(
326
+ self,
327
+ sql: str,
328
+ parameters: "Optional[StatementParameterType]" = None,
329
+ /,
330
+ *,
331
+ connection: "Optional[SqliteConnection]" = None,
332
+ schema_type: None = None,
333
+ **kwargs: Any,
334
+ ) -> "dict[str, Any]": ...
335
+ @overload
336
+ def insert_update_delete_returning(
337
+ self,
338
+ sql: str,
339
+ parameters: "Optional[StatementParameterType]" = None,
340
+ /,
341
+ *,
342
+ connection: "Optional[SqliteConnection]" = None,
343
+ schema_type: "type[ModelDTOT]",
344
+ **kwargs: Any,
345
+ ) -> "ModelDTOT": ...
206
346
  def insert_update_delete_returning(
207
347
  self,
208
348
  sql: str,
209
349
  parameters: Optional["StatementParameterType"] = None,
210
350
  /,
211
351
  *,
212
- connection: Optional["Connection"] = None,
352
+ connection: Optional["SqliteConnection"] = None,
213
353
  schema_type: "Optional[type[ModelDTOT]]" = None,
214
354
  **kwargs: Any,
215
355
  ) -> "Optional[Union[dict[str, Any], ModelDTOT]]":
@@ -253,7 +393,7 @@ class SqliteDriver(SyncDriverAdapterProtocol["Connection"]):
253
393
  parameters: Optional["StatementParameterType"] = None,
254
394
  /,
255
395
  *,
256
- connection: Optional["Connection"] = None,
396
+ connection: Optional["SqliteConnection"] = None,
257
397
  **kwargs: Any,
258
398
  ) -> str:
259
399
  """Execute a script.
@@ -272,34 +412,3 @@ class SqliteDriver(SyncDriverAdapterProtocol["Connection"]):
272
412
  cursor.execute(sql, parameters)
273
413
 
274
414
  return cast("str", cursor.statusmessage) if hasattr(cursor, "statusmessage") else "DONE" # pyright: ignore[reportUnknownMemberType,reportAttributeAccessIssue]
275
-
276
- def execute_script_returning(
277
- self,
278
- sql: str,
279
- parameters: Optional["StatementParameterType"] = None,
280
- /,
281
- *,
282
- connection: Optional["Connection"] = None,
283
- schema_type: "Optional[type[ModelDTOT]]" = None,
284
- **kwargs: Any,
285
- ) -> "Optional[Union[dict[str, Any], ModelDTOT]]":
286
- """Execute a script and return result.
287
-
288
- Returns:
289
- The first row of results.
290
- """
291
- connection = self._connection(connection)
292
- sql, parameters = self._process_sql_params(sql, parameters, **kwargs)
293
-
294
- with self._with_cursor(connection) as cursor:
295
- if not parameters:
296
- cursor.execute(sql) # pyright: ignore[reportUnknownMemberType]
297
- else:
298
- cursor.execute(sql, parameters)
299
- result = cursor.fetchall()
300
- if len(result) == 0:
301
- return None
302
- column_names = [c[0] for c in cursor.description or []]
303
- if schema_type is not None:
304
- return cast("ModelDTOT", schema_type(**dict(zip(column_names, result[0]))))
305
- return dict(zip(column_names, result[0]))