sqlakit 0.2.0__tar.gz → 0.3.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.
Files changed (26) hide show
  1. {sqlakit-0.2.0 → sqlakit-0.3.1}/PKG-INFO +41 -41
  2. {sqlakit-0.2.0 → sqlakit-0.3.1}/README.md +37 -39
  3. {sqlakit-0.2.0 → sqlakit-0.3.1}/pyproject.toml +5 -4
  4. {sqlakit-0.2.0 → sqlakit-0.3.1}/pyproject.toml.orig +7 -4
  5. {sqlakit-0.2.0 → sqlakit-0.3.1}/LICENSE +0 -0
  6. {sqlakit-0.2.0 → sqlakit-0.3.1}/sqlakit/__init__.py +0 -0
  7. {sqlakit-0.2.0 → sqlakit-0.3.1}/sqlakit/_base.py +0 -0
  8. {sqlakit-0.2.0 → sqlakit-0.3.1}/sqlakit/_db.py +0 -0
  9. {sqlakit-0.2.0 → sqlakit-0.3.1}/sqlakit/_discovery.py +0 -0
  10. {sqlakit-0.2.0 → sqlakit-0.3.1}/sqlakit/_model.py +0 -0
  11. {sqlakit-0.2.0 → sqlakit-0.3.1}/sqlakit/_query.py +0 -0
  12. {sqlakit-0.2.0 → sqlakit-0.3.1}/sqlakit/_recording.py +0 -0
  13. {sqlakit-0.2.0 → sqlakit-0.3.1}/sqlakit/_registry.py +0 -0
  14. {sqlakit-0.2.0 → sqlakit-0.3.1}/sqlakit/_routing.py +0 -0
  15. {sqlakit-0.2.0 → sqlakit-0.3.1}/sqlakit/_sql.py +0 -0
  16. {sqlakit-0.2.0 → sqlakit-0.3.1}/sqlakit/asyncio/__init__.py +0 -0
  17. {sqlakit-0.2.0 → sqlakit-0.3.1}/sqlakit/asyncio/_db.py +0 -0
  18. {sqlakit-0.2.0 → sqlakit-0.3.1}/sqlakit/asyncio/_registry.py +0 -0
  19. {sqlakit-0.2.0 → sqlakit-0.3.1}/sqlakit/asyncio/orm.py +0 -0
  20. {sqlakit-0.2.0 → sqlakit-0.3.1}/sqlakit/asyncio/sql.py +0 -0
  21. {sqlakit-0.2.0 → sqlakit-0.3.1}/sqlakit/exceptions.py +0 -0
  22. {sqlakit-0.2.0 → sqlakit-0.3.1}/sqlakit/orm.py +0 -0
  23. {sqlakit-0.2.0 → sqlakit-0.3.1}/sqlakit/py.typed +0 -0
  24. {sqlakit-0.2.0 → sqlakit-0.3.1}/sqlakit/sql.py +0 -0
  25. {sqlakit-0.2.0 → sqlakit-0.3.1}/sqlakit/testing.py +0 -0
  26. {sqlakit-0.2.0 → sqlakit-0.3.1}/sqlakit/types.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sqlakit
3
- Version: 0.2.0
3
+ Version: 0.3.1
4
4
  Summary: A toolkit for SQLAlchemy applications.
5
5
  Keywords: sqlalchemy,database,orm,sql,asyncio
6
6
  Author: Anton Ruhlov
@@ -18,12 +18,14 @@ Classifier: Programming Language :: Python :: 3.14
18
18
  Classifier: Topic :: Database
19
19
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
20
20
  Classifier: Typing :: Typed
21
- Requires-Dist: sqlalchemy[asyncio]>=2.0.22
21
+ Requires-Dist: sqlalchemy>=2.0.22
22
+ Requires-Dist: sqlalchemy[asyncio]>=2.0.22 ; extra == 'asyncio'
22
23
  Requires-Dist: sqlparse>=0.6.0 ; extra == 'debug'
23
24
  Requires-Dist: jinja2sql>=0.11.0 ; extra == 'sql'
24
25
  Requires-Python: >=3.11
25
26
  Project-URL: Repository, https://github.com/antonrh/sqlakit
26
27
  Project-URL: Documentation, https://github.com/antonrh/sqlakit
28
+ Provides-Extra: asyncio
27
29
  Provides-Extra: debug
28
30
  Provides-Extra: sql
29
31
  Description-Content-Type: text/markdown
@@ -183,44 +185,6 @@ feed.next_cursor
183
185
  feed.previous_cursor
184
186
  ```
185
187
 
186
- ## Active Record
187
-
188
- An instance saves and deletes itself, and the query is available on the class:
189
-
190
- ```python
191
- from sqlalchemy.orm import Mapped, mapped_column
192
-
193
- from sqlakit import Database
194
- from sqlakit.orm import Model
195
-
196
- db = Database("postgresql+psycopg://localhost/app")
197
-
198
-
199
- class Note(Model):
200
- __tablename__ = "notes"
201
-
202
- id: Mapped[int] = mapped_column(primary_key=True)
203
- text: Mapped[str]
204
-
205
-
206
- Note.set_db(db)
207
-
208
- with db.transaction():
209
- note = Note(text="ada")
210
- note.save()
211
-
212
- Note.query.where(Note.text == "ada").all()
213
- note.delete()
214
- ```
215
-
216
- `set_db()` binds a model to a database. Call it on a base class and every model
217
- under it inherits the binding. With the global `db` from the section below you
218
- don't need it at all: the model uses the global registry automatically.
219
-
220
- This layer is optional. Everything else works on plain `SQLAlchemy` models, so
221
- if saving belongs in your repositories or services, skip `sqlakit.orm`
222
- entirely.
223
-
224
188
  ## Testing
225
189
 
226
190
  A test runs inside a transaction that rolls back at the end, so nothing the
@@ -326,10 +290,46 @@ with db.using("replica").connect():
326
290
  list_users() # the models read the replica
327
291
  ```
328
292
 
293
+ ## Active Record
294
+
295
+ An instance saves and deletes itself, and the query is available on the class.
296
+ A model on the registry needs no wiring of its own:
297
+
298
+ ```python
299
+ from sqlalchemy.orm import Mapped, mapped_column
300
+
301
+ from sqlakit import db
302
+ from sqlakit.orm import Model
303
+
304
+
305
+ class Note(Model):
306
+ __tablename__ = "notes"
307
+
308
+ id: Mapped[int] = mapped_column(primary_key=True)
309
+ text: Mapped[str]
310
+
311
+
312
+ with db.transaction():
313
+ note = Note(text="ada").save()
314
+
315
+ Note.query.where(Note.text == "ada").all()
316
+ note.delete()
317
+ ```
318
+
319
+ A model that belongs on another database in the registry names its alias with
320
+ `__db__ = "warehouse"`. With a `Database` of your own, `set_db()` binds the
321
+ model to it. Either goes on a base class, and every model under it inherits
322
+ the binding.
323
+
324
+ This layer is optional. Everything else works on plain `SQLAlchemy` models, so
325
+ if saving belongs in your repositories or services, skip `sqlakit.orm`
326
+ entirely. `SQLModel` classes are `SQLAlchemy` models, and work either way: the
327
+ [examples](examples/) show both.
328
+
329
329
  ## The async API
330
330
 
331
331
  The async API is identical: the same classes, the same methods. Only the import
332
- changes:
332
+ changes. It needs the `sqlakit[asyncio]` extra:
333
333
 
334
334
  ```python
335
335
  from sqlakit.asyncio import Database
@@ -153,44 +153,6 @@ feed.next_cursor
153
153
  feed.previous_cursor
154
154
  ```
155
155
 
156
- ## Active Record
157
-
158
- An instance saves and deletes itself, and the query is available on the class:
159
-
160
- ```python
161
- from sqlalchemy.orm import Mapped, mapped_column
162
-
163
- from sqlakit import Database
164
- from sqlakit.orm import Model
165
-
166
- db = Database("postgresql+psycopg://localhost/app")
167
-
168
-
169
- class Note(Model):
170
- __tablename__ = "notes"
171
-
172
- id: Mapped[int] = mapped_column(primary_key=True)
173
- text: Mapped[str]
174
-
175
-
176
- Note.set_db(db)
177
-
178
- with db.transaction():
179
- note = Note(text="ada")
180
- note.save()
181
-
182
- Note.query.where(Note.text == "ada").all()
183
- note.delete()
184
- ```
185
-
186
- `set_db()` binds a model to a database. Call it on a base class and every model
187
- under it inherits the binding. With the global `db` from the section below you
188
- don't need it at all: the model uses the global registry automatically.
189
-
190
- This layer is optional. Everything else works on plain `SQLAlchemy` models, so
191
- if saving belongs in your repositories or services, skip `sqlakit.orm`
192
- entirely.
193
-
194
156
  ## Testing
195
157
 
196
158
  A test runs inside a transaction that rolls back at the end, so nothing the
@@ -296,10 +258,46 @@ with db.using("replica").connect():
296
258
  list_users() # the models read the replica
297
259
  ```
298
260
 
261
+ ## Active Record
262
+
263
+ An instance saves and deletes itself, and the query is available on the class.
264
+ A model on the registry needs no wiring of its own:
265
+
266
+ ```python
267
+ from sqlalchemy.orm import Mapped, mapped_column
268
+
269
+ from sqlakit import db
270
+ from sqlakit.orm import Model
271
+
272
+
273
+ class Note(Model):
274
+ __tablename__ = "notes"
275
+
276
+ id: Mapped[int] = mapped_column(primary_key=True)
277
+ text: Mapped[str]
278
+
279
+
280
+ with db.transaction():
281
+ note = Note(text="ada").save()
282
+
283
+ Note.query.where(Note.text == "ada").all()
284
+ note.delete()
285
+ ```
286
+
287
+ A model that belongs on another database in the registry names its alias with
288
+ `__db__ = "warehouse"`. With a `Database` of your own, `set_db()` binds the
289
+ model to it. Either goes on a base class, and every model under it inherits
290
+ the binding.
291
+
292
+ This layer is optional. Everything else works on plain `SQLAlchemy` models, so
293
+ if saving belongs in your repositories or services, skip `sqlakit.orm`
294
+ entirely. `SQLModel` classes are `SQLAlchemy` models, and work either way: the
295
+ [examples](examples/) show both.
296
+
299
297
  ## The async API
300
298
 
301
299
  The async API is identical: the same classes, the same methods. Only the import
302
- changes:
300
+ changes. It needs the `sqlakit[asyncio]` extra:
303
301
 
304
302
  ```python
305
303
  from sqlakit.asyncio import Database
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "sqlakit"
3
- version = "0.2.0"
3
+ version = "0.3.1"
4
4
  description = "A toolkit for SQLAlchemy applications."
5
5
  readme = "README.md"
6
6
  license = "MIT"
@@ -26,7 +26,7 @@ classifiers = [
26
26
  "Typing :: Typed",
27
27
  ]
28
28
  requires-python = ">=3.11"
29
- dependencies = ["sqlalchemy[asyncio]>=2.0.22"]
29
+ dependencies = ["sqlalchemy>=2.0.22"]
30
30
 
31
31
  [[project.authors]]
32
32
  name = "Anton Ruhlov"
@@ -37,6 +37,7 @@ Repository = "https://github.com/antonrh/sqlakit"
37
37
  Documentation = "https://github.com/antonrh/sqlakit"
38
38
 
39
39
  [project.optional-dependencies]
40
+ asyncio = ["sqlalchemy[asyncio]>=2.0.22"]
40
41
  sql = ["jinja2sql>=0.11.0"]
41
42
  debug = ["sqlparse>=0.6.0"]
42
43
 
@@ -162,8 +163,8 @@ skip = "./.venv,./site,./uv.lock,./.git"
162
163
  [dependency-groups]
163
164
  dev = [
164
165
  "pytest>=9.1.1",
165
- "ty>=0.0.72",
166
- "ruff>=0.16.3",
166
+ "ty>=0.0.75",
167
+ "ruff>=0.16.5",
167
168
  "poethepoet>=0.48.0",
168
169
  "anyio>=4.14.2",
169
170
  "trio>=0.34.0",
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "sqlakit"
3
- version = "0.2.0"
3
+ version = "0.3.1"
4
4
  description = "A toolkit for SQLAlchemy applications."
5
5
  readme = "README.md"
6
6
  license = "MIT"
@@ -22,7 +22,7 @@ classifiers = [
22
22
  ]
23
23
  requires-python = ">=3.11"
24
24
  dependencies = [
25
- "sqlalchemy[asyncio]>=2.0.22",
25
+ "sqlalchemy>=2.0.22",
26
26
  ]
27
27
 
28
28
  [project.urls]
@@ -30,6 +30,9 @@ Repository = "https://github.com/antonrh/sqlakit"
30
30
  Documentation = "https://github.com/antonrh/sqlakit"
31
31
 
32
32
  [project.optional-dependencies]
33
+ asyncio = [
34
+ "sqlalchemy[asyncio]>=2.0.22",
35
+ ]
33
36
  sql = [
34
37
  "jinja2sql>=0.11.0",
35
38
  ]
@@ -51,8 +54,8 @@ default-groups = ["dev", "docs"]
51
54
  [dependency-groups]
52
55
  dev = [
53
56
  "pytest>=9.1.1",
54
- "ty>=0.0.72",
55
- "ruff>=0.16.3",
57
+ "ty>=0.0.75",
58
+ "ruff>=0.16.5",
56
59
  "poethepoet>=0.48.0",
57
60
  "anyio>=4.14.2",
58
61
  "trio>=0.34.0",
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes