sqlengine-lite 2.1.1__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.1.1 → sqlengine_lite-2.2.1}/PKG-INFO +94 -20
- {sqlengine_lite-2.1.1 → sqlengine_lite-2.2.1}/README.md +93 -19
- {sqlengine_lite-2.1.1 → 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.1/src/sqlengine/_internal/connection_manager.py +266 -0
- {sqlengine_lite-2.1.1/src/sqlengine/utils → sqlengine_lite-2.2.1/src/sqlengine/_internal}/repr.py +1 -30
- {sqlengine_lite-2.1.1/src/sqlengine/utils → sqlengine_lite-2.2.1/src/sqlengine/_internal}/sqlgen.py +2 -4
- {sqlengine_lite-2.1.1/src/sqlengine/utils → sqlengine_lite-2.2.1/src/sqlengine/_internal}/statements.py +71 -49
- sqlengine_lite-2.2.1/src/sqlengine/_internal/types.py +105 -0
- sqlengine_lite-2.2.1/src/sqlengine/exceptions.py +20 -0
- {sqlengine_lite-2.1.1 → sqlengine_lite-2.2.1}/src/sqlengine/schema.py +1 -1
- sqlengine_lite-2.2.1/src/sqlengine/sqltable.py +511 -0
- sqlengine_lite-2.2.1/src/sqlengine/utils/__init__.py +4 -0
- {sqlengine_lite-2.1.1 → sqlengine_lite-2.2.1}/src/sqlengine/utils/connection.py +29 -20
- sqlengine_lite-2.2.1/src/sqlengine/utils/convert.py +129 -0
- {sqlengine_lite-2.1.1 → sqlengine_lite-2.2.1}/src/sqlengine_lite.egg-info/PKG-INFO +94 -20
- {sqlengine_lite-2.1.1 → sqlengine_lite-2.2.1}/src/sqlengine_lite.egg-info/SOURCES.txt +8 -4
- {sqlengine_lite-2.1.1 → sqlengine_lite-2.2.1}/tests/test.py +281 -45
- sqlengine_lite-2.1.1/src/sqlengine/__init__.py +0 -7
- sqlengine_lite-2.1.1/src/sqlengine/sqltable.py +0 -593
- sqlengine_lite-2.1.1/src/sqlengine/utils/__init__.py +0 -5
- sqlengine_lite-2.1.1/src/sqlengine/utils/types.py +0 -65
- {sqlengine_lite-2.1.1 → sqlengine_lite-2.2.1}/LICENSE +0 -0
- {sqlengine_lite-2.1.1 → sqlengine_lite-2.2.1}/setup.cfg +0 -0
- {sqlengine_lite-2.1.1 → sqlengine_lite-2.2.1}/src/sqlengine_lite.egg-info/dependency_links.txt +0 -0
- {sqlengine_lite-2.1.1 → 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.
|
|
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
|
|
@@ -25,7 +25,9 @@ Dynamic: license-file
|
|
|
25
25
|
- [Delete Query](#delete-query)
|
|
26
26
|
- [Transaction](#transaction)
|
|
27
27
|
- [Get Item](#get-item)
|
|
28
|
+
- [Custom Types](#custom-types)
|
|
28
29
|
- [Csv Converter](#csv-converter)
|
|
30
|
+
- [Pandas-like Converter](#pandas-like-converter)
|
|
29
31
|
- [Full Documentation](#full-documentation)
|
|
30
32
|
|
|
31
33
|
|
|
@@ -44,17 +46,21 @@ Sql-Engine implements Jupyter integration and dynamic schema building. You can e
|
|
|
44
46
|
```py
|
|
45
47
|
from sqlengine import schema
|
|
46
48
|
|
|
47
|
-
table = schema.table_from_database("temp/chinook.db", "
|
|
49
|
+
table = schema.table_from_database("temp/chinook.db", "Album")
|
|
48
50
|
table
|
|
49
51
|
```
|
|
50
52
|
|
|
51
|
-
<table style="border-collapse: collapse; font-size: 14px;"><caption style="font-size: 18px; font-weight: bold;">
|
|
53
|
+
<table style="border-collapse: collapse; font-size: 14px;"><caption style="font-size: 18px; font-weight: bold;">Album</caption><thead><tr><td style="border: 1px solid #555; text-align: center;">AlbumId</td><td style="border: 1px solid #555; text-align: center;">Title</td><td style="border: 1px solid #555; text-align: center;">ArtistId</td></tr></thead><tbody><tr><td style="border: 1px solid #000; text-align: center;">1</td><td style="border: 1px solid #000; text-align: center;">For Those About To Rock We Salute You</td><td style="border: 1px solid #000; text-align: center;">1</td></tr><tr><td style="border: 1px solid #000; text-align: center;">2</td><td style="border: 1px solid #000; text-align: center;">Balls to the Wall</td><td style="border: 1px solid #000; text-align: center;">2</td></tr><tr><td style="border: 1px solid #000; text-align: center;">3</td><td style="border: 1px solid #000; text-align: center;">Restless and Wild</td><td style="border: 1px solid #000; text-align: center;">2</td></tr><tr><td style="border: 1px solid #000; text-align: center;">4</td><td style="border: 1px solid #000; text-align: center;">Let There Be Rock</td><td style="border: 1px solid #000; text-align: center;">1</td></tr><tr><td style="border: 1px solid #000; text-align: center;">5</td><td style="border: 1px solid #000; text-align: center;">Big Ones</td><td style="border: 1px solid #000; text-align: center;">3</td></tr><tr><td style="border: 1px solid #000; text-align: center;">6</td><td style="border: 1px solid #000; text-align: center;">Jagged Little Pill</td><td style="border: 1px solid #000; text-align: center;">4</td></tr><tr><td style="border: 1px solid #000; text-align: center;">7</td><td style="border: 1px solid #000; text-align: center;">Facelift</td><td style="border: 1px solid #000; text-align: center;">5</td></tr><tr><td style="border: 1px solid #000; text-align: center;">8</td><td style="border: 1px solid #000; text-align: center;">Warner 25 Anos</td><td style="border: 1px solid #000; text-align: center;">6</td></tr><tr><td style="border: 1px solid #000; text-align: center;">9</td><td style="border: 1px solid #000; text-align: center;">Plays Metallica By Four Cellos</td><td style="border: 1px solid #000; text-align: center;">7</td></tr><tr><td style="border: 1px solid #000; text-align: center;">10</td><td style="border: 1px solid #000; text-align: center;">Audioslave</td><td style="border: 1px solid #000; text-align: center;">8</td></tr><tr><td colspan="3" style="text-align:center;color:#888;font-style:italic;padding:8px;">... more rows ...</td></tr></tbody></table>
|
|
54
|
+
|
|
55
|
+
Note that GitHub's html rendering is simplified.
|
|
52
56
|
|
|
53
57
|
---
|
|
54
58
|
|
|
55
59
|
You can preview select statements before fetching data to your variables.
|
|
56
60
|
|
|
57
61
|
```py
|
|
62
|
+
table = schema.table_from_database("temp/chinook.db", "Invoice")
|
|
63
|
+
|
|
58
64
|
table.select("InvoiceId", "CustomerId", "BillingAddress", "BillingCountry", "Total")\
|
|
59
65
|
.where\
|
|
60
66
|
.gte("Total", 2.0)\
|
|
@@ -68,7 +74,7 @@ table.select("InvoiceId", "CustomerId", "BillingAddress", "BillingCountry", "Tot
|
|
|
68
74
|
|
|
69
75
|
## Purpose
|
|
70
76
|
|
|
71
|
-
It's a tiny little modern ORM that lets you prototype your databases locally with great flexibility. Also, it can be used in production apps to store and retrieve data, because all select, update, delete queries are parametrized. But it does not restrict you from using your own queries which might not be paramerized with methods like `select.custom()` and `where.custom()`.
|
|
77
|
+
It's a tiny little modern ORM-like that lets you prototype your databases locally with great flexibility. Also, it can be used in production apps to store and retrieve data, because all select, update, delete queries are parametrized. But it does not restrict you from using your own queries which might not be paramerized with methods like `select.custom()` and `where.custom()`.
|
|
72
78
|
|
|
73
79
|
And last (but not least) is data inspection. If you need to quickly inspect existing .db file but don't want to install yet another heavy ORM with a lot of unused dependencies, you might look into Sql-Engine, as it uses only native python modules.
|
|
74
80
|
|
|
@@ -119,27 +125,22 @@ __primary__ : list[str]
|
|
|
119
125
|
More details at [Declaration](https://github.com/suffermuffin/SQL-Engine/blob/main/docs/table_declaration.md#table-declaration).
|
|
120
126
|
|
|
121
127
|
```py
|
|
122
|
-
from sqlengine import SqlTableMixin
|
|
128
|
+
from sqlengine import SqlTableMixin, Primary
|
|
123
129
|
|
|
124
130
|
# Helper constants for column names
|
|
125
|
-
ID
|
|
126
|
-
Name
|
|
131
|
+
ID = "ID"
|
|
132
|
+
Name = "Name"
|
|
127
133
|
Occupation = "Occupation"
|
|
128
|
-
Salary
|
|
134
|
+
Salary = "Salary"
|
|
129
135
|
|
|
130
136
|
|
|
131
137
|
class Employees(SqlTableMixin):
|
|
132
138
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
139
|
+
ID : Primary[int]
|
|
140
|
+
Name : str | None
|
|
141
|
+
Occupation : str
|
|
142
|
+
Salary : float
|
|
136
143
|
|
|
137
|
-
# You may overwrite your insert methods for type consistency
|
|
138
|
-
def insert(self, id : int, name : str, occupation : str, salary : float) -> None:
|
|
139
|
-
return super().insert(id, name, occupation, salary)
|
|
140
|
-
|
|
141
|
-
def upsert(self, id : int, name : str, occupation : str, salary : float) -> None:
|
|
142
|
-
return super().upsert(id, name, occupation, salary)
|
|
143
144
|
```
|
|
144
145
|
|
|
145
146
|
## Instantiation
|
|
@@ -149,8 +150,9 @@ More details at [Instantiation](https://github.com/suffermuffin/SQL-Engine/blob/
|
|
|
149
150
|
```py
|
|
150
151
|
# Create an instance of the table class
|
|
151
152
|
# with provided path to create or connect to
|
|
153
|
+
# `force_drop=True` to overwrite existing table if exists
|
|
152
154
|
|
|
153
|
-
table = Employees("temp/data.db")
|
|
155
|
+
table = Employees("temp/data.db", force_drop=True)
|
|
154
156
|
```
|
|
155
157
|
|
|
156
158
|
## Row insertion
|
|
@@ -161,11 +163,16 @@ table = Employees("temp/data.db")
|
|
|
161
163
|
table.insert(1, "John Doe", "Software Engineer", 75000.0)
|
|
162
164
|
```
|
|
163
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
|
+
|
|
164
172
|
```py
|
|
165
173
|
# Bulk insert multiple rows
|
|
166
174
|
|
|
167
175
|
employees_data = [
|
|
168
|
-
(2, "Jane Smith", "Data Scientist", 80000.0),
|
|
169
176
|
(3, "Alice Johnson", "Product Manager", 90000.0),
|
|
170
177
|
(4, "Bob Brown", "Project Manager", 78000.0),
|
|
171
178
|
(5, "Charlie Davis", "UI/UX Designer", 65000.0),
|
|
@@ -267,6 +274,43 @@ table[4:10:2]
|
|
|
267
274
|
# (8, 'Frank White', 'Quality Assurance', 53000.0)]
|
|
268
275
|
```
|
|
269
276
|
|
|
277
|
+
## Custom Types
|
|
278
|
+
|
|
279
|
+
More details at [Custom Types](https://github.com/suffermuffin/SQL-Engine/blob/main/docs/custom_types.md).
|
|
280
|
+
|
|
281
|
+
```py
|
|
282
|
+
from datetime import datetime
|
|
283
|
+
from sqlengine import SqlTableMixin, Primary
|
|
284
|
+
|
|
285
|
+
class DateTime(datetime):
|
|
286
|
+
|
|
287
|
+
def to_sql(self) -> str:
|
|
288
|
+
return self.strftime("%Y-%m-%d %H:%M")
|
|
289
|
+
|
|
290
|
+
@classmethod
|
|
291
|
+
def from_sql(cls, sql : bytes):
|
|
292
|
+
return cls.fromisoformat(sql.decode('utf-8'))
|
|
293
|
+
|
|
294
|
+
def __repr__(self):
|
|
295
|
+
return f"DateTime({self.time})"
|
|
296
|
+
|
|
297
|
+
|
|
298
|
+
class ReservationIndex(SqlTableMixin):
|
|
299
|
+
|
|
300
|
+
user_id : Primary[int]
|
|
301
|
+
room_id : Primary[str]
|
|
302
|
+
time_at : Primary[DateTime]
|
|
303
|
+
user_name : str | None
|
|
304
|
+
|
|
305
|
+
|
|
306
|
+
table = ReservationIndex("temp/data.db")
|
|
307
|
+
|
|
308
|
+
table.insert(1, "loft_1", DateTime.now(), None)
|
|
309
|
+
table
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
<table style="border-collapse: collapse; font-size: 14px;"><caption style="font-size: 18px; font-weight: bold;">ReservationIndex</caption><thead><tr><td style="border: 1px solid #555; text-align: center;">user_id</td><td style="border: 1px solid #555; text-align: center;">room_id</td><td style="border: 1px solid #555; text-align: center;">time_at</td><td style="border: 1px solid #555; text-align: center;">user_name</td></tr></thead><tbody><tr><td style="border: 1px solid #000; text-align: center;">1</td><td style="border: 1px solid #000; text-align: center;">loft_1</td><td style="border: 1px solid #000; text-align: center;">2026-05-29 21:29:00</td><td style="border: 1px solid #000; text-align: center;">None</td></tr></tbody></table>
|
|
313
|
+
|
|
270
314
|
## Csv Converter
|
|
271
315
|
|
|
272
316
|
```py
|
|
@@ -278,10 +322,40 @@ to_csv(table, "temp/table.csv")
|
|
|
278
322
|
|
|
279
323
|
```py
|
|
280
324
|
# Save query result to csv
|
|
281
|
-
|
|
282
325
|
to_csv(table.select.where.gt(Salary, 70_000), "temp/query.csv")
|
|
283
326
|
```
|
|
284
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
|
+
|
|
285
359
|
# Full Documentation
|
|
286
360
|
|
|
287
361
|
For detailed usage, API reference, and advanced examples, see the [full documentation](https://github.com/suffermuffin/SQL-Engine/blob/main/docs/index.md).
|
|
@@ -13,7 +13,9 @@
|
|
|
13
13
|
- [Delete Query](#delete-query)
|
|
14
14
|
- [Transaction](#transaction)
|
|
15
15
|
- [Get Item](#get-item)
|
|
16
|
+
- [Custom Types](#custom-types)
|
|
16
17
|
- [Csv Converter](#csv-converter)
|
|
18
|
+
- [Pandas-like Converter](#pandas-like-converter)
|
|
17
19
|
- [Full Documentation](#full-documentation)
|
|
18
20
|
|
|
19
21
|
|
|
@@ -32,17 +34,21 @@ Sql-Engine implements Jupyter integration and dynamic schema building. You can e
|
|
|
32
34
|
```py
|
|
33
35
|
from sqlengine import schema
|
|
34
36
|
|
|
35
|
-
table = schema.table_from_database("temp/chinook.db", "
|
|
37
|
+
table = schema.table_from_database("temp/chinook.db", "Album")
|
|
36
38
|
table
|
|
37
39
|
```
|
|
38
40
|
|
|
39
|
-
<table style="border-collapse: collapse; font-size: 14px;"><caption style="font-size: 18px; font-weight: bold;">
|
|
41
|
+
<table style="border-collapse: collapse; font-size: 14px;"><caption style="font-size: 18px; font-weight: bold;">Album</caption><thead><tr><td style="border: 1px solid #555; text-align: center;">AlbumId</td><td style="border: 1px solid #555; text-align: center;">Title</td><td style="border: 1px solid #555; text-align: center;">ArtistId</td></tr></thead><tbody><tr><td style="border: 1px solid #000; text-align: center;">1</td><td style="border: 1px solid #000; text-align: center;">For Those About To Rock We Salute You</td><td style="border: 1px solid #000; text-align: center;">1</td></tr><tr><td style="border: 1px solid #000; text-align: center;">2</td><td style="border: 1px solid #000; text-align: center;">Balls to the Wall</td><td style="border: 1px solid #000; text-align: center;">2</td></tr><tr><td style="border: 1px solid #000; text-align: center;">3</td><td style="border: 1px solid #000; text-align: center;">Restless and Wild</td><td style="border: 1px solid #000; text-align: center;">2</td></tr><tr><td style="border: 1px solid #000; text-align: center;">4</td><td style="border: 1px solid #000; text-align: center;">Let There Be Rock</td><td style="border: 1px solid #000; text-align: center;">1</td></tr><tr><td style="border: 1px solid #000; text-align: center;">5</td><td style="border: 1px solid #000; text-align: center;">Big Ones</td><td style="border: 1px solid #000; text-align: center;">3</td></tr><tr><td style="border: 1px solid #000; text-align: center;">6</td><td style="border: 1px solid #000; text-align: center;">Jagged Little Pill</td><td style="border: 1px solid #000; text-align: center;">4</td></tr><tr><td style="border: 1px solid #000; text-align: center;">7</td><td style="border: 1px solid #000; text-align: center;">Facelift</td><td style="border: 1px solid #000; text-align: center;">5</td></tr><tr><td style="border: 1px solid #000; text-align: center;">8</td><td style="border: 1px solid #000; text-align: center;">Warner 25 Anos</td><td style="border: 1px solid #000; text-align: center;">6</td></tr><tr><td style="border: 1px solid #000; text-align: center;">9</td><td style="border: 1px solid #000; text-align: center;">Plays Metallica By Four Cellos</td><td style="border: 1px solid #000; text-align: center;">7</td></tr><tr><td style="border: 1px solid #000; text-align: center;">10</td><td style="border: 1px solid #000; text-align: center;">Audioslave</td><td style="border: 1px solid #000; text-align: center;">8</td></tr><tr><td colspan="3" style="text-align:center;color:#888;font-style:italic;padding:8px;">... more rows ...</td></tr></tbody></table>
|
|
42
|
+
|
|
43
|
+
Note that GitHub's html rendering is simplified.
|
|
40
44
|
|
|
41
45
|
---
|
|
42
46
|
|
|
43
47
|
You can preview select statements before fetching data to your variables.
|
|
44
48
|
|
|
45
49
|
```py
|
|
50
|
+
table = schema.table_from_database("temp/chinook.db", "Invoice")
|
|
51
|
+
|
|
46
52
|
table.select("InvoiceId", "CustomerId", "BillingAddress", "BillingCountry", "Total")\
|
|
47
53
|
.where\
|
|
48
54
|
.gte("Total", 2.0)\
|
|
@@ -56,7 +62,7 @@ table.select("InvoiceId", "CustomerId", "BillingAddress", "BillingCountry", "Tot
|
|
|
56
62
|
|
|
57
63
|
## Purpose
|
|
58
64
|
|
|
59
|
-
It's a tiny little modern ORM that lets you prototype your databases locally with great flexibility. Also, it can be used in production apps to store and retrieve data, because all select, update, delete queries are parametrized. But it does not restrict you from using your own queries which might not be paramerized with methods like `select.custom()` and `where.custom()`.
|
|
65
|
+
It's a tiny little modern ORM-like that lets you prototype your databases locally with great flexibility. Also, it can be used in production apps to store and retrieve data, because all select, update, delete queries are parametrized. But it does not restrict you from using your own queries which might not be paramerized with methods like `select.custom()` and `where.custom()`.
|
|
60
66
|
|
|
61
67
|
And last (but not least) is data inspection. If you need to quickly inspect existing .db file but don't want to install yet another heavy ORM with a lot of unused dependencies, you might look into Sql-Engine, as it uses only native python modules.
|
|
62
68
|
|
|
@@ -107,27 +113,22 @@ __primary__ : list[str]
|
|
|
107
113
|
More details at [Declaration](https://github.com/suffermuffin/SQL-Engine/blob/main/docs/table_declaration.md#table-declaration).
|
|
108
114
|
|
|
109
115
|
```py
|
|
110
|
-
from sqlengine import SqlTableMixin
|
|
116
|
+
from sqlengine import SqlTableMixin, Primary
|
|
111
117
|
|
|
112
118
|
# Helper constants for column names
|
|
113
|
-
ID
|
|
114
|
-
Name
|
|
119
|
+
ID = "ID"
|
|
120
|
+
Name = "Name"
|
|
115
121
|
Occupation = "Occupation"
|
|
116
|
-
Salary
|
|
122
|
+
Salary = "Salary"
|
|
117
123
|
|
|
118
124
|
|
|
119
125
|
class Employees(SqlTableMixin):
|
|
120
126
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
127
|
+
ID : Primary[int]
|
|
128
|
+
Name : str | None
|
|
129
|
+
Occupation : str
|
|
130
|
+
Salary : float
|
|
124
131
|
|
|
125
|
-
# You may overwrite your insert methods for type consistency
|
|
126
|
-
def insert(self, id : int, name : str, occupation : str, salary : float) -> None:
|
|
127
|
-
return super().insert(id, name, occupation, salary)
|
|
128
|
-
|
|
129
|
-
def upsert(self, id : int, name : str, occupation : str, salary : float) -> None:
|
|
130
|
-
return super().upsert(id, name, occupation, salary)
|
|
131
132
|
```
|
|
132
133
|
|
|
133
134
|
## Instantiation
|
|
@@ -137,8 +138,9 @@ More details at [Instantiation](https://github.com/suffermuffin/SQL-Engine/blob/
|
|
|
137
138
|
```py
|
|
138
139
|
# Create an instance of the table class
|
|
139
140
|
# with provided path to create or connect to
|
|
141
|
+
# `force_drop=True` to overwrite existing table if exists
|
|
140
142
|
|
|
141
|
-
table = Employees("temp/data.db")
|
|
143
|
+
table = Employees("temp/data.db", force_drop=True)
|
|
142
144
|
```
|
|
143
145
|
|
|
144
146
|
## Row insertion
|
|
@@ -149,11 +151,16 @@ table = Employees("temp/data.db")
|
|
|
149
151
|
table.insert(1, "John Doe", "Software Engineer", 75000.0)
|
|
150
152
|
```
|
|
151
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
|
+
|
|
152
160
|
```py
|
|
153
161
|
# Bulk insert multiple rows
|
|
154
162
|
|
|
155
163
|
employees_data = [
|
|
156
|
-
(2, "Jane Smith", "Data Scientist", 80000.0),
|
|
157
164
|
(3, "Alice Johnson", "Product Manager", 90000.0),
|
|
158
165
|
(4, "Bob Brown", "Project Manager", 78000.0),
|
|
159
166
|
(5, "Charlie Davis", "UI/UX Designer", 65000.0),
|
|
@@ -255,6 +262,43 @@ table[4:10:2]
|
|
|
255
262
|
# (8, 'Frank White', 'Quality Assurance', 53000.0)]
|
|
256
263
|
```
|
|
257
264
|
|
|
265
|
+
## Custom Types
|
|
266
|
+
|
|
267
|
+
More details at [Custom Types](https://github.com/suffermuffin/SQL-Engine/blob/main/docs/custom_types.md).
|
|
268
|
+
|
|
269
|
+
```py
|
|
270
|
+
from datetime import datetime
|
|
271
|
+
from sqlengine import SqlTableMixin, Primary
|
|
272
|
+
|
|
273
|
+
class DateTime(datetime):
|
|
274
|
+
|
|
275
|
+
def to_sql(self) -> str:
|
|
276
|
+
return self.strftime("%Y-%m-%d %H:%M")
|
|
277
|
+
|
|
278
|
+
@classmethod
|
|
279
|
+
def from_sql(cls, sql : bytes):
|
|
280
|
+
return cls.fromisoformat(sql.decode('utf-8'))
|
|
281
|
+
|
|
282
|
+
def __repr__(self):
|
|
283
|
+
return f"DateTime({self.time})"
|
|
284
|
+
|
|
285
|
+
|
|
286
|
+
class ReservationIndex(SqlTableMixin):
|
|
287
|
+
|
|
288
|
+
user_id : Primary[int]
|
|
289
|
+
room_id : Primary[str]
|
|
290
|
+
time_at : Primary[DateTime]
|
|
291
|
+
user_name : str | None
|
|
292
|
+
|
|
293
|
+
|
|
294
|
+
table = ReservationIndex("temp/data.db")
|
|
295
|
+
|
|
296
|
+
table.insert(1, "loft_1", DateTime.now(), None)
|
|
297
|
+
table
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
<table style="border-collapse: collapse; font-size: 14px;"><caption style="font-size: 18px; font-weight: bold;">ReservationIndex</caption><thead><tr><td style="border: 1px solid #555; text-align: center;">user_id</td><td style="border: 1px solid #555; text-align: center;">room_id</td><td style="border: 1px solid #555; text-align: center;">time_at</td><td style="border: 1px solid #555; text-align: center;">user_name</td></tr></thead><tbody><tr><td style="border: 1px solid #000; text-align: center;">1</td><td style="border: 1px solid #000; text-align: center;">loft_1</td><td style="border: 1px solid #000; text-align: center;">2026-05-29 21:29:00</td><td style="border: 1px solid #000; text-align: center;">None</td></tr></tbody></table>
|
|
301
|
+
|
|
258
302
|
## Csv Converter
|
|
259
303
|
|
|
260
304
|
```py
|
|
@@ -266,10 +310,40 @@ to_csv(table, "temp/table.csv")
|
|
|
266
310
|
|
|
267
311
|
```py
|
|
268
312
|
# Save query result to csv
|
|
269
|
-
|
|
270
313
|
to_csv(table.select.where.gt(Salary, 70_000), "temp/query.csv")
|
|
271
314
|
```
|
|
272
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
|
+
|
|
273
347
|
# Full Documentation
|
|
274
348
|
|
|
275
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.
|
|
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
|
+
]
|