sqlengine-lite 2.2.0__tar.gz → 2.2.1__tar.gz
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.
- {sqlengine_lite-2.2.0/src/sqlengine_lite.egg-info → sqlengine_lite-2.2.1}/PKG-INFO +43 -13
- {sqlengine_lite-2.2.0 → sqlengine_lite-2.2.1}/README.md +42 -12
- {sqlengine_lite-2.2.0 → sqlengine_lite-2.2.1}/pyproject.toml +8 -2
- sqlengine_lite-2.2.1/src/sqlengine/__init__.py +11 -0
- sqlengine_lite-2.2.1/src/sqlengine/_internal/__init__.py +4 -0
- sqlengine_lite-2.2.0/src/sqlengine/core/connection.py → sqlengine_lite-2.2.1/src/sqlengine/_internal/connection_manager.py +17 -6
- {sqlengine_lite-2.2.0/src/sqlengine/core → sqlengine_lite-2.2.1/src/sqlengine/_internal}/statements.py +36 -14
- {sqlengine_lite-2.2.0/src/sqlengine/core → sqlengine_lite-2.2.1/src/sqlengine/_internal}/types.py +9 -8
- sqlengine_lite-2.2.1/src/sqlengine/exceptions.py +20 -0
- {sqlengine_lite-2.2.0 → sqlengine_lite-2.2.1}/src/sqlengine/schema.py +1 -1
- {sqlengine_lite-2.2.0 → sqlengine_lite-2.2.1}/src/sqlengine/sqltable.py +98 -66
- sqlengine_lite-2.2.1/src/sqlengine/utils/__init__.py +4 -0
- {sqlengine_lite-2.2.0 → sqlengine_lite-2.2.1}/src/sqlengine/utils/connection.py +11 -8
- sqlengine_lite-2.2.1/src/sqlengine/utils/convert.py +129 -0
- {sqlengine_lite-2.2.0 → sqlengine_lite-2.2.1/src/sqlengine_lite.egg-info}/PKG-INFO +43 -13
- {sqlengine_lite-2.2.0 → sqlengine_lite-2.2.1}/src/sqlengine_lite.egg-info/SOURCES.txt +7 -6
- {sqlengine_lite-2.2.0 → sqlengine_lite-2.2.1}/tests/test.py +165 -30
- sqlengine_lite-2.2.0/src/sqlengine/__init__.py +0 -7
- sqlengine_lite-2.2.0/src/sqlengine/core/__init__.py +0 -4
- sqlengine_lite-2.2.0/src/sqlengine/utils/__init__.py +0 -4
- sqlengine_lite-2.2.0/src/sqlengine/utils/convert.py +0 -24
- {sqlengine_lite-2.2.0 → sqlengine_lite-2.2.1}/LICENSE +0 -0
- {sqlengine_lite-2.2.0 → sqlengine_lite-2.2.1}/setup.cfg +0 -0
- {sqlengine_lite-2.2.0/src/sqlengine/core → sqlengine_lite-2.2.1/src/sqlengine/_internal}/repr.py +0 -0
- {sqlengine_lite-2.2.0/src/sqlengine/core → sqlengine_lite-2.2.1/src/sqlengine/_internal}/sqlgen.py +0 -0
- {sqlengine_lite-2.2.0 → sqlengine_lite-2.2.1}/src/sqlengine_lite.egg-info/dependency_links.txt +0 -0
- {sqlengine_lite-2.2.0 → sqlengine_lite-2.2.1}/src/sqlengine_lite.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: sqlengine-lite
|
|
3
|
-
Version: 2.2.
|
|
3
|
+
Version: 2.2.1
|
|
4
4
|
Summary: Cute sqlite3 wrapper for sql tables
|
|
5
5
|
Project-URL: Homepage, https://github.com/suffermuffin/SQL-Engine
|
|
6
6
|
Project-URL: Repository, https://github.com/suffermuffin/SQL-Engine.git
|
|
@@ -27,6 +27,7 @@ Dynamic: license-file
|
|
|
27
27
|
- [Get Item](#get-item)
|
|
28
28
|
- [Custom Types](#custom-types)
|
|
29
29
|
- [Csv Converter](#csv-converter)
|
|
30
|
+
- [Pandas-like Converter](#pandas-like-converter)
|
|
30
31
|
- [Full Documentation](#full-documentation)
|
|
31
32
|
|
|
32
33
|
|
|
@@ -127,25 +128,19 @@ More details at [Declaration](https://github.com/suffermuffin/SQL-Engine/blob/ma
|
|
|
127
128
|
from sqlengine import SqlTableMixin, Primary
|
|
128
129
|
|
|
129
130
|
# Helper constants for column names
|
|
130
|
-
ID
|
|
131
|
-
Name
|
|
131
|
+
ID = "ID"
|
|
132
|
+
Name = "Name"
|
|
132
133
|
Occupation = "Occupation"
|
|
133
|
-
Salary
|
|
134
|
+
Salary = "Salary"
|
|
134
135
|
|
|
135
136
|
|
|
136
137
|
class Employees(SqlTableMixin):
|
|
137
138
|
|
|
138
139
|
ID : Primary[int]
|
|
139
|
-
Name : str
|
|
140
|
+
Name : str | None
|
|
140
141
|
Occupation : str
|
|
141
142
|
Salary : float
|
|
142
143
|
|
|
143
|
-
# You may overwrite your insert methods for type consistency
|
|
144
|
-
def insert(self, id : int, name : str, occupation : str, salary : float) -> None:
|
|
145
|
-
return super().insert(id, name, occupation, salary)
|
|
146
|
-
|
|
147
|
-
def upsert(self, id : int, name : str, occupation : str, salary : float) -> None:
|
|
148
|
-
return super().upsert(id, name, occupation, salary)
|
|
149
144
|
```
|
|
150
145
|
|
|
151
146
|
## Instantiation
|
|
@@ -168,11 +163,16 @@ table = Employees("temp/data.db", force_drop=True)
|
|
|
168
163
|
table.insert(1, "John Doe", "Software Engineer", 75000.0)
|
|
169
164
|
```
|
|
170
165
|
|
|
166
|
+
```py
|
|
167
|
+
# Use kwargs mapping to insert/upsert one row
|
|
168
|
+
|
|
169
|
+
table.insert(2, salary=80000.0, name="Jane Smith", occupation="Data Scientist")
|
|
170
|
+
```
|
|
171
|
+
|
|
171
172
|
```py
|
|
172
173
|
# Bulk insert multiple rows
|
|
173
174
|
|
|
174
175
|
employees_data = [
|
|
175
|
-
(2, "Jane Smith", "Data Scientist", 80000.0),
|
|
176
176
|
(3, "Alice Johnson", "Product Manager", 90000.0),
|
|
177
177
|
(4, "Bob Brown", "Project Manager", 78000.0),
|
|
178
178
|
(5, "Charlie Davis", "UI/UX Designer", 65000.0),
|
|
@@ -322,10 +322,40 @@ to_csv(table, "temp/table.csv")
|
|
|
322
322
|
|
|
323
323
|
```py
|
|
324
324
|
# Save query result to csv
|
|
325
|
-
|
|
326
325
|
to_csv(table.select.where.gt(Salary, 70_000), "temp/query.csv")
|
|
327
326
|
```
|
|
328
327
|
|
|
328
|
+
```py
|
|
329
|
+
# Stream to csv
|
|
330
|
+
with table.transaction():
|
|
331
|
+
to_csv(table, "temp/query.csv", stream_batch_size=1000)
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
## Pandas-like Converter
|
|
335
|
+
|
|
336
|
+
```py
|
|
337
|
+
# via one shot
|
|
338
|
+
import pandas as pd
|
|
339
|
+
from sqlengine.utils import to_dicts
|
|
340
|
+
|
|
341
|
+
df = pd.DataFrame(to_dicts(table))
|
|
342
|
+
df.set_index("ID", inplace=True)
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
```py
|
|
346
|
+
# via generator
|
|
347
|
+
import pandas as pd
|
|
348
|
+
from sqlengine.utils import to_dicts_stream
|
|
349
|
+
|
|
350
|
+
df = pd.DataFrame(columns=table.columns)
|
|
351
|
+
|
|
352
|
+
with table.transaction():
|
|
353
|
+
for batch in to_dicts_stream(table, batch_size=1000):
|
|
354
|
+
df = pd.concat([df, pd.DataFrame(batch)], axis=0)
|
|
355
|
+
|
|
356
|
+
df.set_index("ID", inplace=True)
|
|
357
|
+
```
|
|
358
|
+
|
|
329
359
|
# Full Documentation
|
|
330
360
|
|
|
331
361
|
For detailed usage, API reference, and advanced examples, see the [full documentation](https://github.com/suffermuffin/SQL-Engine/blob/main/docs/index.md).
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
- [Get Item](#get-item)
|
|
16
16
|
- [Custom Types](#custom-types)
|
|
17
17
|
- [Csv Converter](#csv-converter)
|
|
18
|
+
- [Pandas-like Converter](#pandas-like-converter)
|
|
18
19
|
- [Full Documentation](#full-documentation)
|
|
19
20
|
|
|
20
21
|
|
|
@@ -115,25 +116,19 @@ More details at [Declaration](https://github.com/suffermuffin/SQL-Engine/blob/ma
|
|
|
115
116
|
from sqlengine import SqlTableMixin, Primary
|
|
116
117
|
|
|
117
118
|
# Helper constants for column names
|
|
118
|
-
ID
|
|
119
|
-
Name
|
|
119
|
+
ID = "ID"
|
|
120
|
+
Name = "Name"
|
|
120
121
|
Occupation = "Occupation"
|
|
121
|
-
Salary
|
|
122
|
+
Salary = "Salary"
|
|
122
123
|
|
|
123
124
|
|
|
124
125
|
class Employees(SqlTableMixin):
|
|
125
126
|
|
|
126
127
|
ID : Primary[int]
|
|
127
|
-
Name : str
|
|
128
|
+
Name : str | None
|
|
128
129
|
Occupation : str
|
|
129
130
|
Salary : float
|
|
130
131
|
|
|
131
|
-
# You may overwrite your insert methods for type consistency
|
|
132
|
-
def insert(self, id : int, name : str, occupation : str, salary : float) -> None:
|
|
133
|
-
return super().insert(id, name, occupation, salary)
|
|
134
|
-
|
|
135
|
-
def upsert(self, id : int, name : str, occupation : str, salary : float) -> None:
|
|
136
|
-
return super().upsert(id, name, occupation, salary)
|
|
137
132
|
```
|
|
138
133
|
|
|
139
134
|
## Instantiation
|
|
@@ -156,11 +151,16 @@ table = Employees("temp/data.db", force_drop=True)
|
|
|
156
151
|
table.insert(1, "John Doe", "Software Engineer", 75000.0)
|
|
157
152
|
```
|
|
158
153
|
|
|
154
|
+
```py
|
|
155
|
+
# Use kwargs mapping to insert/upsert one row
|
|
156
|
+
|
|
157
|
+
table.insert(2, salary=80000.0, name="Jane Smith", occupation="Data Scientist")
|
|
158
|
+
```
|
|
159
|
+
|
|
159
160
|
```py
|
|
160
161
|
# Bulk insert multiple rows
|
|
161
162
|
|
|
162
163
|
employees_data = [
|
|
163
|
-
(2, "Jane Smith", "Data Scientist", 80000.0),
|
|
164
164
|
(3, "Alice Johnson", "Product Manager", 90000.0),
|
|
165
165
|
(4, "Bob Brown", "Project Manager", 78000.0),
|
|
166
166
|
(5, "Charlie Davis", "UI/UX Designer", 65000.0),
|
|
@@ -310,10 +310,40 @@ to_csv(table, "temp/table.csv")
|
|
|
310
310
|
|
|
311
311
|
```py
|
|
312
312
|
# Save query result to csv
|
|
313
|
-
|
|
314
313
|
to_csv(table.select.where.gt(Salary, 70_000), "temp/query.csv")
|
|
315
314
|
```
|
|
316
315
|
|
|
316
|
+
```py
|
|
317
|
+
# Stream to csv
|
|
318
|
+
with table.transaction():
|
|
319
|
+
to_csv(table, "temp/query.csv", stream_batch_size=1000)
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
## Pandas-like Converter
|
|
323
|
+
|
|
324
|
+
```py
|
|
325
|
+
# via one shot
|
|
326
|
+
import pandas as pd
|
|
327
|
+
from sqlengine.utils import to_dicts
|
|
328
|
+
|
|
329
|
+
df = pd.DataFrame(to_dicts(table))
|
|
330
|
+
df.set_index("ID", inplace=True)
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
```py
|
|
334
|
+
# via generator
|
|
335
|
+
import pandas as pd
|
|
336
|
+
from sqlengine.utils import to_dicts_stream
|
|
337
|
+
|
|
338
|
+
df = pd.DataFrame(columns=table.columns)
|
|
339
|
+
|
|
340
|
+
with table.transaction():
|
|
341
|
+
for batch in to_dicts_stream(table, batch_size=1000):
|
|
342
|
+
df = pd.concat([df, pd.DataFrame(batch)], axis=0)
|
|
343
|
+
|
|
344
|
+
df.set_index("ID", inplace=True)
|
|
345
|
+
```
|
|
346
|
+
|
|
317
347
|
# Full Documentation
|
|
318
348
|
|
|
319
349
|
For detailed usage, API reference, and advanced examples, see the [full documentation](https://github.com/suffermuffin/SQL-Engine/blob/main/docs/index.md).
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "sqlengine-lite"
|
|
3
|
-
version = "2.2.
|
|
3
|
+
version = "2.2.1"
|
|
4
4
|
description = "Cute sqlite3 wrapper for sql tables"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.12"
|
|
@@ -19,7 +19,13 @@ where = ["src"]
|
|
|
19
19
|
requires = ["setuptools>=61.0"]
|
|
20
20
|
build-backend = "setuptools.build_meta"
|
|
21
21
|
|
|
22
|
+
[dependency-groups]
|
|
23
|
+
dev = [
|
|
24
|
+
"black==26.5.1",
|
|
25
|
+
"pydoc-markdown>=4.8.2",
|
|
26
|
+
]
|
|
27
|
+
|
|
22
28
|
[project.urls]
|
|
23
29
|
Homepage = "https://github.com/suffermuffin/SQL-Engine"
|
|
24
30
|
Repository = "https://github.com/suffermuffin/SQL-Engine.git"
|
|
25
|
-
Documentation = "https://github.com/suffermuffin/SQL-Engine/blob/main/docs/index.md"
|
|
31
|
+
Documentation = "https://github.com/suffermuffin/SQL-Engine/blob/main/docs/index.md"
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
from ._internal import sqlgen
|
|
2
|
+
from ._internal import ConnectionManager
|
|
3
|
+
from ._internal.types import Schema, Primary, register_type
|
|
4
|
+
from .sqltable import SqlTableMixin
|
|
5
|
+
|
|
6
|
+
__author__ = "suffermuffin"
|
|
7
|
+
|
|
8
|
+
__all__ = [
|
|
9
|
+
"sqlgen", "Schema", "SqlTableMixin",
|
|
10
|
+
"Primary", "ConnectionManager", "register_type"
|
|
11
|
+
]
|
|
@@ -6,6 +6,7 @@ from typing import overload, Literal, Sequence
|
|
|
6
6
|
from contextlib import contextmanager
|
|
7
7
|
|
|
8
8
|
from .types import SqlValue, SqlRow
|
|
9
|
+
from ..exceptions import TransactionError, NestedTransactionError, OutsideTransactionError
|
|
9
10
|
|
|
10
11
|
|
|
11
12
|
logger = logging.getLogger("sqlengine")
|
|
@@ -14,6 +15,16 @@ logger.setLevel(os.getenv("SQL_ENGINE_LOG_LEVEL", "WARNING").upper())
|
|
|
14
15
|
|
|
15
16
|
class ConnectionManager:
|
|
16
17
|
|
|
18
|
+
"""
|
|
19
|
+
Connection manager for sqlite3
|
|
20
|
+
|
|
21
|
+
Args:
|
|
22
|
+
|
|
23
|
+
database (str): database filename to connect to. If `":memory:"` is passed, then database will be set in memory and you will have to
|
|
24
|
+
create table manually with `create_table()` method inside `transaction()` block.
|
|
25
|
+
**connection_params: Params to create connection with. Reference: https://docs.python.org/3/library/sqlite3.html#sqlite3.connect
|
|
26
|
+
"""
|
|
27
|
+
|
|
17
28
|
_trans : sqlite3.Connection
|
|
18
29
|
_trans_cursor : sqlite3.Cursor
|
|
19
30
|
|
|
@@ -172,7 +183,7 @@ class ConnectionManager:
|
|
|
172
183
|
def open(self) -> None:
|
|
173
184
|
""" Opens unmanaged transaction """
|
|
174
185
|
if self.in_transaction():
|
|
175
|
-
raise
|
|
186
|
+
raise NestedTransactionError("Can't re-open existing connection")
|
|
176
187
|
|
|
177
188
|
self._trans = self.connect()
|
|
178
189
|
self._trans_cursor = self._trans.cursor()
|
|
@@ -184,7 +195,7 @@ class ConnectionManager:
|
|
|
184
195
|
return
|
|
185
196
|
|
|
186
197
|
if self._is_managed_transaction:
|
|
187
|
-
raise
|
|
198
|
+
raise TransactionError("Can't manually close managed transaction")
|
|
188
199
|
|
|
189
200
|
self._trans_cursor.close()
|
|
190
201
|
self._trans.close()
|
|
@@ -194,14 +205,14 @@ class ConnectionManager:
|
|
|
194
205
|
|
|
195
206
|
def commit(self) -> None:
|
|
196
207
|
if not self.in_transaction():
|
|
197
|
-
raise
|
|
208
|
+
raise OutsideTransactionError("Can't commit outside transaction mode")
|
|
198
209
|
|
|
199
210
|
self._trans.commit()
|
|
200
211
|
|
|
201
212
|
|
|
202
213
|
def rollback(self) -> None:
|
|
203
214
|
if not self.in_transaction():
|
|
204
|
-
raise
|
|
215
|
+
raise OutsideTransactionError("Can't rollback outside transaction mode")
|
|
205
216
|
|
|
206
217
|
self._trans.rollback()
|
|
207
218
|
|
|
@@ -242,7 +253,7 @@ class ConnectionManager:
|
|
|
242
253
|
def tx_conn(self) -> sqlite3.Connection:
|
|
243
254
|
""" Gives access to connection while in transaction """
|
|
244
255
|
if not self.in_transaction():
|
|
245
|
-
raise
|
|
256
|
+
raise OutsideTransactionError("`tx_conn` is not available outside the transaction mode")
|
|
246
257
|
return self._trans
|
|
247
258
|
|
|
248
259
|
|
|
@@ -250,6 +261,6 @@ class ConnectionManager:
|
|
|
250
261
|
def tx_cursor(self) -> sqlite3.Cursor:
|
|
251
262
|
""" Gives access to connection cursor while in transaction """
|
|
252
263
|
if not self.in_transaction():
|
|
253
|
-
raise
|
|
264
|
+
raise OutsideTransactionError("`tx_cursor` is not available outside the transaction mode")
|
|
254
265
|
return self._trans_cursor
|
|
255
266
|
|
|
@@ -2,10 +2,11 @@ from typing import Sequence, Literal, Generator, Self
|
|
|
2
2
|
from abc import ABC, abstractmethod
|
|
3
3
|
|
|
4
4
|
from . import sqlgen as sql
|
|
5
|
-
from .
|
|
5
|
+
from .connection_manager import ConnectionManager
|
|
6
6
|
|
|
7
7
|
from .types import SqlValue, SqlRow, Schema
|
|
8
8
|
from .repr import to_html
|
|
9
|
+
from ..exceptions import SqlEngineError, OutsideTransactionError
|
|
9
10
|
|
|
10
11
|
|
|
11
12
|
class Where[T : "Statement"]:
|
|
@@ -146,7 +147,7 @@ class Statement(ABC):
|
|
|
146
147
|
|
|
147
148
|
self._tableschema = tableschema
|
|
148
149
|
self._connection = connection
|
|
149
|
-
self._where
|
|
150
|
+
self._where = Where(self)
|
|
150
151
|
|
|
151
152
|
self._custom_query : str | None = None
|
|
152
153
|
self._custom_args : tuple[SqlValue, ...] = ()
|
|
@@ -206,6 +207,7 @@ class Statement(ABC):
|
|
|
206
207
|
class MutationalStatement(Statement, ABC):
|
|
207
208
|
|
|
208
209
|
def execute(self) -> None:
|
|
210
|
+
""" Execute built statement """
|
|
209
211
|
query, args = self.build()
|
|
210
212
|
self._connection.execute(query, *args)
|
|
211
213
|
|
|
@@ -222,46 +224,52 @@ class Select(Statement):
|
|
|
222
224
|
|
|
223
225
|
|
|
224
226
|
def __call__(self, *columns : str) -> Self:
|
|
227
|
+
""" Shortcut to columns selector """
|
|
225
228
|
return self.columns(*columns)
|
|
226
229
|
|
|
227
230
|
|
|
228
231
|
def columns(self, *columns : str) -> Self:
|
|
229
|
-
"""
|
|
232
|
+
""" Columns selector """
|
|
230
233
|
self._columns.extend(columns)
|
|
231
234
|
return self
|
|
232
235
|
|
|
233
236
|
|
|
234
237
|
def aggregate(self, by : Literal['COUNT', 'SUM', 'AVG', 'MIN', 'MAX']) -> Self:
|
|
235
|
-
|
|
238
|
+
""" Aggregate by provided method """
|
|
236
239
|
if self._aggregate:
|
|
237
|
-
raise
|
|
240
|
+
raise SqlEngineError("Can't aggregate columns multiple times")
|
|
238
241
|
|
|
239
242
|
self._aggregate = by
|
|
240
243
|
return self
|
|
241
244
|
|
|
242
245
|
|
|
243
246
|
def order_by(self, column : str, ascending : bool = True) -> Self:
|
|
247
|
+
""" Orders returned rows by provided column """
|
|
244
248
|
order = "ASC" if ascending else "DESC"
|
|
245
249
|
self._order_by.append(f"{column} {order}")
|
|
246
250
|
return self
|
|
247
251
|
|
|
248
252
|
|
|
249
253
|
def limit(self, n : int) -> Self:
|
|
254
|
+
""" Limit number of returned rows """
|
|
250
255
|
self._limit = n
|
|
251
256
|
return self
|
|
252
257
|
|
|
253
258
|
|
|
254
259
|
def fetchone(self) -> SqlRow:
|
|
260
|
+
""" Fetch first row """
|
|
255
261
|
query, args = self.build()
|
|
256
262
|
return self._connection.fetchone(query, *args)
|
|
257
263
|
|
|
258
264
|
|
|
259
265
|
def fetchmany(self, size : int = 1) -> list[SqlRow]:
|
|
266
|
+
""" Fetch first `size` rows """
|
|
260
267
|
query, args = self.build()
|
|
261
268
|
return self._connection.fetchmany(query, *args, size=size)
|
|
262
269
|
|
|
263
270
|
|
|
264
271
|
def fetchall(self) -> list[SqlRow]:
|
|
272
|
+
""" Fetch all rows """
|
|
265
273
|
query, args = self.build()
|
|
266
274
|
return self._connection.fetchall(query, *args)
|
|
267
275
|
|
|
@@ -275,13 +283,15 @@ class Select(Statement):
|
|
|
275
283
|
|
|
276
284
|
Examples:
|
|
277
285
|
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
286
|
+
```python
|
|
287
|
+
with table.transaction():
|
|
288
|
+
for batch in table.select.where.gt("Age", 30).then.fetchmany_iterator(1000):
|
|
289
|
+
process_batch(batch)
|
|
290
|
+
```
|
|
281
291
|
"""
|
|
282
292
|
if not self._connection.in_transaction():
|
|
283
|
-
raise
|
|
284
|
-
to keep open the transaction of the table
|
|
293
|
+
raise OutsideTransactionError("To use the `fetchall_iterator()` method you have \
|
|
294
|
+
to keep open the transaction of the table")
|
|
285
295
|
|
|
286
296
|
query, exec_args = self.build()
|
|
287
297
|
|
|
@@ -293,11 +303,22 @@ class Select(Statement):
|
|
|
293
303
|
|
|
294
304
|
|
|
295
305
|
def __iter__(self) -> Generator[SqlRow, None, None]:
|
|
296
|
-
"""
|
|
306
|
+
"""
|
|
307
|
+
Select statement rows iterator
|
|
308
|
+
|
|
309
|
+
Examples:
|
|
310
|
+
|
|
311
|
+
```python
|
|
312
|
+
with table.transaction():
|
|
313
|
+
# here `then` is used to link back to the `select` instance from `where` object
|
|
314
|
+
for row in table.select.where.gt("Age", 30).then:
|
|
315
|
+
process_row(row)
|
|
316
|
+
```
|
|
317
|
+
"""
|
|
297
318
|
|
|
298
319
|
if not self._connection.in_transaction():
|
|
299
|
-
raise
|
|
300
|
-
to keep open the transaction of the table
|
|
320
|
+
raise OutsideTransactionError("To use the __iter__ method you have \
|
|
321
|
+
to keep open the transaction of the table")
|
|
301
322
|
|
|
302
323
|
query, exec_args = self.build()
|
|
303
324
|
|
|
@@ -360,7 +381,7 @@ class Delete(MutationalStatement):
|
|
|
360
381
|
def _build(self, where_clause : str, *args : SqlValue) -> tuple[str, tuple[SqlValue, ...]]:
|
|
361
382
|
|
|
362
383
|
if not where_clause:
|
|
363
|
-
raise
|
|
384
|
+
raise SqlEngineError("Delete statement must have a where clause")
|
|
364
385
|
|
|
365
386
|
query = sql.delete_rows(self._tableschema["tablename"], where_clause)
|
|
366
387
|
return query, args
|
|
@@ -379,6 +400,7 @@ class Update(MutationalStatement):
|
|
|
379
400
|
|
|
380
401
|
|
|
381
402
|
def __call__(self, column : str, value : SqlValue) -> Self:
|
|
403
|
+
""" Shortcut to set value to a column """
|
|
382
404
|
return self.set(column, value)
|
|
383
405
|
|
|
384
406
|
|
{sqlengine_lite-2.2.0/src/sqlengine/core → sqlengine_lite-2.2.1/src/sqlengine/_internal}/types.py
RENAMED
|
@@ -12,15 +12,16 @@ class CustomType(Protocol):
|
|
|
12
12
|
...
|
|
13
13
|
|
|
14
14
|
|
|
15
|
-
type SqlValue
|
|
16
|
-
type SqlRow
|
|
17
|
-
type SqlType
|
|
15
|
+
type SqlValue = str | int | float | bytes | None | CustomType
|
|
16
|
+
type SqlRow = tuple[SqlValue, ...]
|
|
17
|
+
type SqlType = type[str | int | float | bytes | CustomType]
|
|
18
|
+
type ColumnType = SqlType | str | UnionType
|
|
18
19
|
|
|
19
20
|
|
|
20
21
|
class Schema(TypedDict):
|
|
21
22
|
tablename : str
|
|
22
23
|
columns : list[str]
|
|
23
|
-
types : list[
|
|
24
|
+
types : list[ColumnType]
|
|
24
25
|
primary : list[str]
|
|
25
26
|
|
|
26
27
|
|
|
@@ -41,7 +42,7 @@ _TYPES_MAP : dict[type | UnionType, str] = {
|
|
|
41
42
|
}
|
|
42
43
|
|
|
43
44
|
|
|
44
|
-
def is_custom_type(type_: SqlType) -> TypeGuard[type[CustomType]]:
|
|
45
|
+
def is_custom_type(type_: SqlType | UnionType) -> TypeGuard[type[CustomType]]:
|
|
45
46
|
return (
|
|
46
47
|
type_ not in (str, int, float, bytes)
|
|
47
48
|
and isinstance(type_, type)
|
|
@@ -52,7 +53,7 @@ def is_custom_type(type_: SqlType) -> TypeGuard[type[CustomType]]:
|
|
|
52
53
|
|
|
53
54
|
def register_type(cls : type[CustomType], type_name : str | None = None) -> None:
|
|
54
55
|
"""
|
|
55
|
-
Register custom type to be able to store it in tables
|
|
56
|
+
Register custom type into sqlite3 to be able to store it in tables
|
|
56
57
|
|
|
57
58
|
Args:
|
|
58
59
|
cls (CustomType): Class that implements `from_sql(cls, sql : bytes) -> Self` and `
|
|
@@ -65,7 +66,7 @@ def register_type(cls : type[CustomType], type_name : str | None = None) -> None
|
|
|
65
66
|
sqlite3.register_converter(type_name, cls.from_sql)
|
|
66
67
|
|
|
67
68
|
|
|
68
|
-
def pytype_to_sqltype(type_ : type) -> str:
|
|
69
|
+
def pytype_to_sqltype(type_ : type | UnionType) -> str:
|
|
69
70
|
""" Converts python type to sql type """
|
|
70
71
|
if type_ not in _TYPES_MAP:
|
|
71
72
|
raise TypeError(f"{type_} is not natively supported by sqlite3")
|
|
@@ -73,7 +74,7 @@ def pytype_to_sqltype(type_ : type) -> str:
|
|
|
73
74
|
return _TYPES_MAP[type_]
|
|
74
75
|
|
|
75
76
|
|
|
76
|
-
def register_resolve_types(types : list[
|
|
77
|
+
def register_resolve_types(types : list[ColumnType], **connection_params) -> tuple[list[str], dict[str, Any]]:
|
|
77
78
|
""" Converts py types to sql types, registers custom types, resolves type names, updates connection params """
|
|
78
79
|
|
|
79
80
|
resolved : list[str] = []
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
|
|
2
|
+
class SqlEngineError(Exception):
|
|
3
|
+
""" Errors linked to sqlengine module """
|
|
4
|
+
pass
|
|
5
|
+
|
|
6
|
+
class TransactionError(SqlEngineError):
|
|
7
|
+
""" Errors within transactions """
|
|
8
|
+
pass
|
|
9
|
+
|
|
10
|
+
class OutsideTransactionError(TransactionError):
|
|
11
|
+
""" Errors of prohibited outside tranasctions operations """
|
|
12
|
+
pass
|
|
13
|
+
|
|
14
|
+
class NestedTransactionError(TransactionError):
|
|
15
|
+
""" Errors of nested transaction operations """
|
|
16
|
+
pass
|
|
17
|
+
|
|
18
|
+
class TableDeclarationError(SqlEngineError):
|
|
19
|
+
""" Errors of table declaration """
|
|
20
|
+
pass
|