sqlspec 0.8.0__py3-none-any.whl → 0.9.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 (45) hide show
  1. sqlspec/_typing.py +39 -6
  2. sqlspec/adapters/adbc/__init__.py +2 -2
  3. sqlspec/adapters/adbc/config.py +34 -11
  4. sqlspec/adapters/adbc/driver.py +167 -108
  5. sqlspec/adapters/aiosqlite/__init__.py +2 -2
  6. sqlspec/adapters/aiosqlite/config.py +2 -2
  7. sqlspec/adapters/aiosqlite/driver.py +28 -39
  8. sqlspec/adapters/asyncmy/__init__.py +3 -3
  9. sqlspec/adapters/asyncmy/config.py +11 -12
  10. sqlspec/adapters/asyncmy/driver.py +25 -34
  11. sqlspec/adapters/asyncpg/__init__.py +5 -5
  12. sqlspec/adapters/asyncpg/config.py +17 -19
  13. sqlspec/adapters/asyncpg/driver.py +249 -93
  14. sqlspec/adapters/duckdb/__init__.py +2 -2
  15. sqlspec/adapters/duckdb/config.py +2 -2
  16. sqlspec/adapters/duckdb/driver.py +49 -49
  17. sqlspec/adapters/oracledb/__init__.py +8 -8
  18. sqlspec/adapters/oracledb/config/__init__.py +6 -6
  19. sqlspec/adapters/oracledb/config/_asyncio.py +9 -10
  20. sqlspec/adapters/oracledb/config/_sync.py +8 -9
  21. sqlspec/adapters/oracledb/driver.py +114 -41
  22. sqlspec/adapters/psqlpy/__init__.py +0 -0
  23. sqlspec/adapters/psqlpy/config.py +258 -0
  24. sqlspec/adapters/psqlpy/driver.py +335 -0
  25. sqlspec/adapters/psycopg/__init__.py +10 -5
  26. sqlspec/adapters/psycopg/config/__init__.py +6 -6
  27. sqlspec/adapters/psycopg/config/_async.py +12 -12
  28. sqlspec/adapters/psycopg/config/_sync.py +13 -13
  29. sqlspec/adapters/psycopg/driver.py +180 -218
  30. sqlspec/adapters/sqlite/__init__.py +2 -2
  31. sqlspec/adapters/sqlite/config.py +2 -2
  32. sqlspec/adapters/sqlite/driver.py +43 -41
  33. sqlspec/base.py +275 -153
  34. sqlspec/exceptions.py +30 -0
  35. sqlspec/extensions/litestar/config.py +6 -0
  36. sqlspec/extensions/litestar/handlers.py +25 -0
  37. sqlspec/extensions/litestar/plugin.py +6 -1
  38. sqlspec/statement.py +373 -0
  39. sqlspec/typing.py +10 -1
  40. {sqlspec-0.8.0.dist-info → sqlspec-0.9.0.dist-info}/METADATA +4 -1
  41. sqlspec-0.9.0.dist-info/RECORD +61 -0
  42. sqlspec-0.8.0.dist-info/RECORD +0 -57
  43. {sqlspec-0.8.0.dist-info → sqlspec-0.9.0.dist-info}/WHEEL +0 -0
  44. {sqlspec-0.8.0.dist-info → sqlspec-0.9.0.dist-info}/licenses/LICENSE +0 -0
  45. {sqlspec-0.8.0.dist-info → sqlspec-0.9.0.dist-info}/licenses/NOTICE +0 -0
@@ -1,7 +1,7 @@
1
- from sqlspec.adapters.sqlite.config import Sqlite
1
+ from sqlspec.adapters.sqlite.config import SqliteConfig
2
2
  from sqlspec.adapters.sqlite.driver import SqliteDriver
3
3
 
4
4
  __all__ = (
5
- "Sqlite",
5
+ "SqliteConfig",
6
6
  "SqliteDriver",
7
7
  )
@@ -12,11 +12,11 @@ if TYPE_CHECKING:
12
12
  from collections.abc import Generator
13
13
 
14
14
 
15
- __all__ = ("Sqlite",)
15
+ __all__ = ("SqliteConfig",)
16
16
 
17
17
 
18
18
  @dataclass
19
- class Sqlite(NoPoolSyncConfig["Connection", "SqliteDriver"]):
19
+ class SqliteConfig(NoPoolSyncConfig["Connection", "SqliteDriver"]):
20
20
  """Configuration for SQLite database connections.
21
21
 
22
22
  This class provides configuration options for SQLite database connections, wrapping all parameters
@@ -16,6 +16,7 @@ class SqliteDriver(SyncDriverAdapterProtocol["Connection"]):
16
16
  """SQLite Sync Driver Adapter."""
17
17
 
18
18
  connection: "Connection"
19
+ dialect: str = "sqlite"
19
20
 
20
21
  def __init__(self, connection: "Connection") -> None:
21
22
  self.connection = connection
@@ -37,8 +38,10 @@ class SqliteDriver(SyncDriverAdapterProtocol["Connection"]):
37
38
  sql: str,
38
39
  parameters: Optional["StatementParameterType"] = None,
39
40
  /,
41
+ *,
40
42
  connection: Optional["Connection"] = None,
41
43
  schema_type: "Optional[type[ModelDTOT]]" = None,
44
+ **kwargs: Any,
42
45
  ) -> "list[Union[ModelDTOT, dict[str, Any]]]":
43
46
  """Fetch data from the database.
44
47
 
@@ -46,7 +49,7 @@ class SqliteDriver(SyncDriverAdapterProtocol["Connection"]):
46
49
  List of row data as either model instances or dictionaries.
47
50
  """
48
51
  connection = self._connection(connection)
49
- sql, parameters = self._process_sql_params(sql, parameters)
52
+ sql, parameters = self._process_sql_params(sql, parameters, **kwargs)
50
53
  with self._with_cursor(connection) as cursor:
51
54
  if not parameters:
52
55
  cursor.execute(sql) # pyright: ignore[reportUnknownMemberType]
@@ -65,8 +68,10 @@ class SqliteDriver(SyncDriverAdapterProtocol["Connection"]):
65
68
  sql: str,
66
69
  parameters: Optional["StatementParameterType"] = None,
67
70
  /,
71
+ *,
68
72
  connection: Optional["Connection"] = None,
69
73
  schema_type: "Optional[type[ModelDTOT]]" = None,
74
+ **kwargs: Any,
70
75
  ) -> "Union[ModelDTOT, dict[str, Any]]":
71
76
  """Fetch one row from the database.
72
77
 
@@ -74,7 +79,7 @@ class SqliteDriver(SyncDriverAdapterProtocol["Connection"]):
74
79
  The first row of the query results.
75
80
  """
76
81
  connection = self._connection(connection)
77
- sql, parameters = self._process_sql_params(sql, parameters)
82
+ sql, parameters = self._process_sql_params(sql, parameters, **kwargs)
78
83
  with self._with_cursor(connection) as cursor:
79
84
  if not parameters:
80
85
  cursor.execute(sql) # pyright: ignore[reportUnknownMemberType]
@@ -92,8 +97,10 @@ class SqliteDriver(SyncDriverAdapterProtocol["Connection"]):
92
97
  sql: str,
93
98
  parameters: Optional["StatementParameterType"] = None,
94
99
  /,
100
+ *,
95
101
  connection: Optional["Connection"] = None,
96
102
  schema_type: "Optional[type[ModelDTOT]]" = None,
103
+ **kwargs: Any,
97
104
  ) -> "Optional[Union[ModelDTOT, dict[str, Any]]]":
98
105
  """Fetch one row from the database.
99
106
 
@@ -101,7 +108,7 @@ class SqliteDriver(SyncDriverAdapterProtocol["Connection"]):
101
108
  The first row of the query results.
102
109
  """
103
110
  connection = self._connection(connection)
104
- sql, parameters = self._process_sql_params(sql, parameters)
111
+ sql, parameters = self._process_sql_params(sql, parameters, **kwargs)
105
112
  with self._with_cursor(connection) as cursor:
106
113
  if not parameters:
107
114
  cursor.execute(sql) # pyright: ignore[reportUnknownMemberType]
@@ -120,8 +127,10 @@ class SqliteDriver(SyncDriverAdapterProtocol["Connection"]):
120
127
  sql: str,
121
128
  parameters: "Optional[StatementParameterType]" = None,
122
129
  /,
130
+ *,
123
131
  connection: "Optional[Connection]" = None,
124
132
  schema_type: "Optional[type[T]]" = None,
133
+ **kwargs: Any,
125
134
  ) -> "Union[T, Any]":
126
135
  """Fetch a single value from the database.
127
136
 
@@ -129,7 +138,7 @@ class SqliteDriver(SyncDriverAdapterProtocol["Connection"]):
129
138
  The first value from the first row of results, or None if no results.
130
139
  """
131
140
  connection = self._connection(connection)
132
- sql, parameters = self._process_sql_params(sql, parameters)
141
+ sql, parameters = self._process_sql_params(sql, parameters, **kwargs)
133
142
  with self._with_cursor(connection) as cursor:
134
143
  if not parameters:
135
144
  cursor.execute(sql) # pyright: ignore[reportUnknownMemberType]
@@ -146,8 +155,10 @@ class SqliteDriver(SyncDriverAdapterProtocol["Connection"]):
146
155
  sql: str,
147
156
  parameters: "Optional[StatementParameterType]" = None,
148
157
  /,
158
+ *,
149
159
  connection: "Optional[Connection]" = None,
150
160
  schema_type: "Optional[type[T]]" = None,
161
+ **kwargs: Any,
151
162
  ) -> "Optional[Union[T, Any]]":
152
163
  """Fetch a single value from the database.
153
164
 
@@ -155,7 +166,7 @@ class SqliteDriver(SyncDriverAdapterProtocol["Connection"]):
155
166
  The first value from the first row of results, or None if no results.
156
167
  """
157
168
  connection = self._connection(connection)
158
- sql, parameters = self._process_sql_params(sql, parameters)
169
+ sql, parameters = self._process_sql_params(sql, parameters, **kwargs)
159
170
  with self._with_cursor(connection) as cursor:
160
171
  if not parameters:
161
172
  cursor.execute(sql) # pyright: ignore[reportUnknownMemberType]
@@ -173,7 +184,9 @@ class SqliteDriver(SyncDriverAdapterProtocol["Connection"]):
173
184
  sql: str,
174
185
  parameters: Optional["StatementParameterType"] = None,
175
186
  /,
187
+ *,
176
188
  connection: Optional["Connection"] = None,
189
+ **kwargs: Any,
177
190
  ) -> int:
178
191
  """Insert, update, or delete data from the database.
179
192
 
@@ -181,7 +194,7 @@ class SqliteDriver(SyncDriverAdapterProtocol["Connection"]):
181
194
  Row count affected by the operation.
182
195
  """
183
196
  connection = self._connection(connection)
184
- sql, parameters = self._process_sql_params(sql, parameters)
197
+ sql, parameters = self._process_sql_params(sql, parameters, **kwargs)
185
198
 
186
199
  with self._with_cursor(connection) as cursor:
187
200
  if not parameters:
@@ -195,8 +208,10 @@ class SqliteDriver(SyncDriverAdapterProtocol["Connection"]):
195
208
  sql: str,
196
209
  parameters: Optional["StatementParameterType"] = None,
197
210
  /,
211
+ *,
198
212
  connection: Optional["Connection"] = None,
199
213
  schema_type: "Optional[type[ModelDTOT]]" = None,
214
+ **kwargs: Any,
200
215
  ) -> "Optional[Union[dict[str, Any], ModelDTOT]]":
201
216
  """Insert, update, or delete data from the database and return result.
202
217
 
@@ -204,7 +219,7 @@ class SqliteDriver(SyncDriverAdapterProtocol["Connection"]):
204
219
  The first row of results.
205
220
  """
206
221
  connection = self._connection(connection)
207
- sql, parameters = self._process_sql_params(sql, parameters)
222
+ sql, parameters = self._process_sql_params(sql, parameters, **kwargs)
208
223
 
209
224
  with self._with_cursor(connection) as cursor:
210
225
  if not parameters:
@@ -214,46 +229,32 @@ class SqliteDriver(SyncDriverAdapterProtocol["Connection"]):
214
229
  result = cursor.fetchall()
215
230
  if len(result) == 0:
216
231
  return None
217
- column_names = [c[0] for c in cursor.description or []]
218
- if schema_type is not None:
219
- return cast("ModelDTOT", schema_type(**dict(zip(column_names, result[0]))))
220
- return dict(zip(column_names, result[0]))
221
-
222
- def _process_sql_params(
223
- self, sql: str, parameters: "Optional[StatementParameterType]" = None
224
- ) -> "tuple[str, Optional[Union[tuple[Any, ...], list[Any], dict[str, Any]]]]":
225
- """Process SQL query and parameters for DB-API execution.
226
232
 
227
- Converts named parameters (:name) to positional parameters (?) for SQLite.
233
+ # Get column names from cursor description
234
+ column_names = [c[0] for c in cursor.description or []]
228
235
 
229
- Args:
230
- sql: The SQL query string.
231
- parameters: The parameters for the query (dict, tuple, list, or None).
236
+ # Get the first row's values - ensure we're getting the actual values
237
+ row_values = result[0]
232
238
 
233
- Returns:
234
- A tuple containing the processed SQL string and the processed parameters.
235
- """
236
- if not isinstance(parameters, dict) or not parameters:
237
- # If parameters are not a dict, or empty dict, assume positional/no params
238
- # Let the underlying driver handle tuples/lists directly
239
- return sql, parameters
239
+ # Debug print to see what we're getting
240
240
 
241
- # Convert named parameters to positional parameters
242
- processed_sql = sql
243
- processed_params: list[Any] = []
244
- for key, value in parameters.items():
245
- # Replace :key with ? in the SQL
246
- processed_sql = processed_sql.replace(f":{key}", "?")
247
- processed_params.append(value)
241
+ # Create dictionary mapping column names to values
242
+ result_dict = {}
243
+ for i, col_name in enumerate(column_names):
244
+ result_dict[col_name] = row_values[i]
248
245
 
249
- return processed_sql, tuple(processed_params)
246
+ if schema_type is not None:
247
+ return cast("ModelDTOT", schema_type(**result_dict))
248
+ return result_dict
250
249
 
251
250
  def execute_script(
252
251
  self,
253
252
  sql: str,
254
253
  parameters: Optional["StatementParameterType"] = None,
255
254
  /,
255
+ *,
256
256
  connection: Optional["Connection"] = None,
257
+ **kwargs: Any,
257
258
  ) -> str:
258
259
  """Execute a script.
259
260
 
@@ -261,25 +262,26 @@ class SqliteDriver(SyncDriverAdapterProtocol["Connection"]):
261
262
  Status message for the operation.
262
263
  """
263
264
  connection = self._connection(connection)
265
+ sql, parameters = self._process_sql_params(sql, parameters, **kwargs)
264
266
 
265
- # For DDL statements, don't pass parameters to execute
266
- # SQLite doesn't support parameters for DDL statements
267
+ # The _process_sql_params handles parameter formatting for the dialect.
267
268
  with self._with_cursor(connection) as cursor:
268
269
  if not parameters:
269
270
  cursor.execute(sql) # pyright: ignore[reportUnknownMemberType]
270
271
  else:
271
- sql, parameters = self._process_sql_params(sql, parameters)
272
- cursor.execute(sql, parameters) # type: ignore[arg-type]
272
+ cursor.execute(sql, parameters)
273
273
 
274
- return cast("str", cursor.statusmessage) if hasattr(cursor, "statusmessage") else "DONE" # pyright: ignore[reportUnknownMemberType,reportAttributeAccessIssue]
274
+ return cast("str", cursor.statusmessage) if hasattr(cursor, "statusmessage") else "DONE" # pyright: ignore[reportUnknownMemberType,reportAttributeAccessIssue]
275
275
 
276
276
  def execute_script_returning(
277
277
  self,
278
278
  sql: str,
279
279
  parameters: Optional["StatementParameterType"] = None,
280
280
  /,
281
+ *,
281
282
  connection: Optional["Connection"] = None,
282
283
  schema_type: "Optional[type[ModelDTOT]]" = None,
284
+ **kwargs: Any,
283
285
  ) -> "Optional[Union[dict[str, Any], ModelDTOT]]":
284
286
  """Execute a script and return result.
285
287
 
@@ -287,7 +289,7 @@ class SqliteDriver(SyncDriverAdapterProtocol["Connection"]):
287
289
  The first row of results.
288
290
  """
289
291
  connection = self._connection(connection)
290
- sql, parameters = self._process_sql_params(sql, parameters)
292
+ sql, parameters = self._process_sql_params(sql, parameters, **kwargs)
291
293
 
292
294
  with self._with_cursor(connection) as cursor:
293
295
  if not parameters: