nexorm 0.1.0__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.
- nexorm-0.1.0/PKG-INFO +299 -0
- nexorm-0.1.0/README.md +270 -0
- nexorm-0.1.0/pyproject.toml +56 -0
- nexorm-0.1.0/setup.cfg +4 -0
- nexorm-0.1.0/src/nexorm/__init__.py +41 -0
- nexorm-0.1.0/src/nexorm/__main__.py +5 -0
- nexorm-0.1.0/src/nexorm/cli.py +78 -0
- nexorm-0.1.0/src/nexorm/database.py +116 -0
- nexorm-0.1.0/src/nexorm/dialects/__init__.py +5 -0
- nexorm-0.1.0/src/nexorm/dialects/base.py +76 -0
- nexorm-0.1.0/src/nexorm/dialects/postgres.py +7 -0
- nexorm-0.1.0/src/nexorm/dialects/sqlite.py +7 -0
- nexorm-0.1.0/src/nexorm/exceptions.py +22 -0
- nexorm-0.1.0/src/nexorm/fields.py +166 -0
- nexorm-0.1.0/src/nexorm/lookups.py +29 -0
- nexorm-0.1.0/src/nexorm/manager.py +42 -0
- nexorm-0.1.0/src/nexorm/migrations/__init__.py +1 -0
- nexorm-0.1.0/src/nexorm/migrations/autodetector.py +44 -0
- nexorm-0.1.0/src/nexorm/migrations/engine.py +116 -0
- nexorm-0.1.0/src/nexorm/migrations/operations.py +238 -0
- nexorm-0.1.0/src/nexorm/migrations/state.py +51 -0
- nexorm-0.1.0/src/nexorm/migrations/writer.py +41 -0
- nexorm-0.1.0/src/nexorm/model.py +74 -0
- nexorm-0.1.0/src/nexorm/options.py +32 -0
- nexorm-0.1.0/src/nexorm/query.py +101 -0
- nexorm-0.1.0/src/nexorm/raw.py +16 -0
- nexorm-0.1.0/src/nexorm/registry.py +31 -0
- nexorm-0.1.0/src/nexorm/relations.py +62 -0
- nexorm-0.1.0/src/nexorm/sql/__init__.py +4 -0
- nexorm-0.1.0/src/nexorm/sql/compiler.py +51 -0
- nexorm-0.1.0/src/nexorm/sql/crud.py +66 -0
- nexorm-0.1.0/src/nexorm/sql/expressions.py +55 -0
- nexorm-0.1.0/src/nexorm/transaction.py +13 -0
- nexorm-0.1.0/src/nexorm/validators.py +61 -0
- nexorm-0.1.0/src/nexorm.egg-info/PKG-INFO +299 -0
- nexorm-0.1.0/src/nexorm.egg-info/SOURCES.txt +39 -0
- nexorm-0.1.0/src/nexorm.egg-info/dependency_links.txt +1 -0
- nexorm-0.1.0/src/nexorm.egg-info/entry_points.txt +2 -0
- nexorm-0.1.0/src/nexorm.egg-info/requires.txt +6 -0
- nexorm-0.1.0/src/nexorm.egg-info/top_level.txt +1 -0
- nexorm-0.1.0/tests/test_basic.py +57 -0
nexorm-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: nexorm
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A minimal Django-style ORM for SQLite applications.
|
|
5
|
+
Author: Admin12121
|
|
6
|
+
Project-URL: Homepage, https://github.com/Admin12121/nexorm
|
|
7
|
+
Project-URL: Repository, https://github.com/Admin12121/nexorm
|
|
8
|
+
Project-URL: Issues, https://github.com/Admin12121/nexorm/issues
|
|
9
|
+
Keywords: orm,sqlite,database,migrations,model
|
|
10
|
+
Classifier: Development Status :: 3 - Alpha
|
|
11
|
+
Classifier: Environment :: Console
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: Operating System :: OS Independent
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
20
|
+
Classifier: Topic :: Database
|
|
21
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
22
|
+
Requires-Python: >=3.10
|
|
23
|
+
Description-Content-Type: text/markdown
|
|
24
|
+
Provides-Extra: dev
|
|
25
|
+
Requires-Dist: build>=1.2; extra == "dev"
|
|
26
|
+
Requires-Dist: pytest>=8; extra == "dev"
|
|
27
|
+
Requires-Dist: ruff>=0.5; extra == "dev"
|
|
28
|
+
Requires-Dist: twine>=5; extra == "dev"
|
|
29
|
+
|
|
30
|
+
<h3 align="center">NexORM</h3>
|
|
31
|
+
|
|
32
|
+
<p align="center">
|
|
33
|
+
A minimal Python ORM for SQLite apps with models, query helpers, transactions, migrations, and named database connections.
|
|
34
|
+
</p>
|
|
35
|
+
|
|
36
|
+
<p align="center">
|
|
37
|
+
<a href="https://pypi.org/project/nexorm/">
|
|
38
|
+
<img alt="Release" src="https://img.shields.io/badge/release-v0.1.0-f2c6c2?style=for-the-badge&labelColor=2f2d42">
|
|
39
|
+
</a>
|
|
40
|
+
<a href="https://github.com/Admin12121/nexorm/stargazers">
|
|
41
|
+
<img alt="Stars" src="https://img.shields.io/github/stars/Admin12121/nexorm?style=for-the-badge&labelColor=34364d&color=b8b8f3">
|
|
42
|
+
</a>
|
|
43
|
+
<a href="https://github.com/Admin12121/nexorm/issues">
|
|
44
|
+
<img alt="Issues" src="https://img.shields.io/github/issues/Admin12121/nexorm?style=for-the-badge&labelColor=34364d&color=f4a77c">
|
|
45
|
+
</a>
|
|
46
|
+
<a href="https://github.com/Admin12121/nexorm/graphs/contributors">
|
|
47
|
+
<img alt="Contributors" src="https://img.shields.io/github/contributors/Admin12121/nexorm?style=for-the-badge&labelColor=34364d&color=a7dc9a">
|
|
48
|
+
</a>
|
|
49
|
+
</p>
|
|
50
|
+
|
|
51
|
+
## Installation
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
pip install nexorm
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
For local development:
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
python -m pip install -e ".[dev]"
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Quick Start
|
|
64
|
+
|
|
65
|
+
Initialize NexORM in your project:
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
nexorm init
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
This creates a local `manage.py` file and a `migrations/` directory:
|
|
72
|
+
|
|
73
|
+
```text
|
|
74
|
+
manage.py
|
|
75
|
+
migrations/
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
After that, you can use NexORM through `python manage.py`, similar to Django.
|
|
79
|
+
|
|
80
|
+
Define models in your app, for example `app/models.py`:
|
|
81
|
+
|
|
82
|
+
```python
|
|
83
|
+
from nexorm import ForeignKey, IntegerField, Model, StringField
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
class User(Model):
|
|
87
|
+
id = IntegerField(primary_key=True, auto_increment=True)
|
|
88
|
+
username = StringField(max_length=100, unique=True, index=True)
|
|
89
|
+
|
|
90
|
+
class Meta:
|
|
91
|
+
table_name = "users"
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
class Post(Model):
|
|
95
|
+
id = IntegerField(primary_key=True, auto_increment=True)
|
|
96
|
+
title = StringField(max_length=200)
|
|
97
|
+
user_id = ForeignKey("User", on_delete="CASCADE", related_name="posts")
|
|
98
|
+
|
|
99
|
+
class Meta:
|
|
100
|
+
table_name = "posts"
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Generate and apply migrations:
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
python manage.py makemigrations
|
|
107
|
+
python manage.py migrate
|
|
108
|
+
python manage.py showmigrations
|
|
109
|
+
python manage.py rollback
|
|
110
|
+
python manage.py sqlmigrate 0001_create_table_users.py
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
By default, `manage.py` uses `db.sqlite3` and imports models from `app.models`.
|
|
114
|
+
You can override both:
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
python manage.py --database local.sqlite3 --models myproject.models makemigrations
|
|
118
|
+
python manage.py --database local.sqlite3 --models myproject.models migrate
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
Use the ORM:
|
|
122
|
+
|
|
123
|
+
```python
|
|
124
|
+
from nexorm import configure, transaction
|
|
125
|
+
from app.models import Post, User
|
|
126
|
+
|
|
127
|
+
configure("db.sqlite3")
|
|
128
|
+
|
|
129
|
+
user = User.objects.create(username="admin")
|
|
130
|
+
post = Post.objects.create(title="Hello", user_id=user.id)
|
|
131
|
+
|
|
132
|
+
same_user = User.objects.filter(username__contains="adm").first()
|
|
133
|
+
recent_posts = user.posts.order_by("-id").limit(10).all()
|
|
134
|
+
|
|
135
|
+
with transaction.atomic():
|
|
136
|
+
User.objects.create(username="vicky")
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
Use raw SQL only with parameters:
|
|
140
|
+
|
|
141
|
+
```python
|
|
142
|
+
user = User.objects.raw("SELECT * FROM users WHERE id = ?", [1]).first()
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
Use with Flask:
|
|
146
|
+
|
|
147
|
+
```python
|
|
148
|
+
from flask import Flask
|
|
149
|
+
from nexorm import configure
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
def create_app():
|
|
153
|
+
configure("db.sqlite3")
|
|
154
|
+
app = Flask(__name__)
|
|
155
|
+
return app
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
## Models
|
|
159
|
+
|
|
160
|
+
Define models by subclassing `Model` and assigning field instances. If a model does not define a primary key, NexORM adds an auto-incrementing `id` field.
|
|
161
|
+
|
|
162
|
+
```python
|
|
163
|
+
from nexorm import BooleanField, DateTimeField, IntegerField, Model, StringField
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
class Article(Model):
|
|
167
|
+
title = StringField(max_length=180)
|
|
168
|
+
views = IntegerField(default=0)
|
|
169
|
+
published = BooleanField(default=False)
|
|
170
|
+
created_at = DateTimeField(nullable=True)
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
## Queries
|
|
174
|
+
|
|
175
|
+
```python
|
|
176
|
+
Post.objects.create(title="First post", user_id=1)
|
|
177
|
+
|
|
178
|
+
posts = Post.objects.filter(title__contains="First").order_by("-id").limit(10).all()
|
|
179
|
+
count = Post.objects.filter(user_id=1).count()
|
|
180
|
+
exists = Post.objects.filter(title="First post").exists()
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
Supported lookup suffixes include exact matching and common comparisons such as `gt`, `gte`, `lt`, `lte`, `contains`, `startswith`, `endswith`, and `in`.
|
|
184
|
+
|
|
185
|
+
## Multiple Databases
|
|
186
|
+
|
|
187
|
+
Configure the default connection:
|
|
188
|
+
|
|
189
|
+
```python
|
|
190
|
+
from nexorm import configure
|
|
191
|
+
|
|
192
|
+
configure("db.sqlite3")
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
Configure named connections:
|
|
196
|
+
|
|
197
|
+
```python
|
|
198
|
+
from nexorm import configure, transaction
|
|
199
|
+
from app.models import User
|
|
200
|
+
|
|
201
|
+
configure("db.sqlite3")
|
|
202
|
+
configure("analytics.sqlite3", alias="analytics")
|
|
203
|
+
|
|
204
|
+
admin = User.objects.create(username="admin")
|
|
205
|
+
report_user = User.objects.using("analytics").create(username="report")
|
|
206
|
+
|
|
207
|
+
analytics_users = User.objects.using("analytics").filter(username__contains="rep").all()
|
|
208
|
+
|
|
209
|
+
with transaction.atomic("analytics"):
|
|
210
|
+
User.objects.using("analytics").create(username="worker")
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
You can also pass a `Database` instance directly to `using(...)` or `transaction.atomic(...)`.
|
|
214
|
+
|
|
215
|
+
## Transactions
|
|
216
|
+
|
|
217
|
+
```python
|
|
218
|
+
from nexorm import transaction
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
with transaction.atomic():
|
|
222
|
+
Post.objects.create(title="Inside a transaction", user_id=1)
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
Nested transactions use SQLite savepoints.
|
|
226
|
+
|
|
227
|
+
## Migrations CLI
|
|
228
|
+
|
|
229
|
+
Initialize a project:
|
|
230
|
+
|
|
231
|
+
```bash
|
|
232
|
+
nexorm init
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
That command creates this local `manage.py` file:
|
|
236
|
+
|
|
237
|
+
```python
|
|
238
|
+
from nexorm.cli import main
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
if __name__ == "__main__":
|
|
242
|
+
main()
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
Generate and apply migrations:
|
|
246
|
+
|
|
247
|
+
```bash
|
|
248
|
+
python manage.py makemigrations
|
|
249
|
+
python manage.py migrate
|
|
250
|
+
python manage.py showmigrations
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
Other commands:
|
|
254
|
+
|
|
255
|
+
```bash
|
|
256
|
+
python manage.py rollback
|
|
257
|
+
python manage.py sqlmigrate 0001_initial.py
|
|
258
|
+
python manage.py dbshell
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
You can still use the installed `nexorm` command directly:
|
|
262
|
+
|
|
263
|
+
```bash
|
|
264
|
+
nexorm --database app.sqlite3 --models app.models makemigrations
|
|
265
|
+
nexorm --database app.sqlite3 --models app.models migrate
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
## Build
|
|
269
|
+
|
|
270
|
+
```bash
|
|
271
|
+
python -m pip install --upgrade build twine
|
|
272
|
+
python -m build
|
|
273
|
+
python -m twine check dist/*
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
## Publish to PyPI
|
|
277
|
+
|
|
278
|
+
Create an API token in PyPI, then upload manually:
|
|
279
|
+
|
|
280
|
+
```bash
|
|
281
|
+
python -m twine upload dist/*
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
When prompted:
|
|
285
|
+
|
|
286
|
+
```text
|
|
287
|
+
username: __token__
|
|
288
|
+
password: pypi-...
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
Use TestPyPI first if you want a dry run:
|
|
292
|
+
|
|
293
|
+
```bash
|
|
294
|
+
python -m twine upload --repository testpypi dist/*
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
## Status
|
|
298
|
+
|
|
299
|
+
NexORM is an early package. The current implementation focuses on SQLite and keeps the public API small: model fields, managers/querysets, raw queries, transactions, named connections, and file-based migrations.
|
nexorm-0.1.0/README.md
ADDED
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
<h3 align="center">NexORM</h3>
|
|
2
|
+
|
|
3
|
+
<p align="center">
|
|
4
|
+
A minimal Python ORM for SQLite apps with models, query helpers, transactions, migrations, and named database connections.
|
|
5
|
+
</p>
|
|
6
|
+
|
|
7
|
+
<p align="center">
|
|
8
|
+
<a href="https://pypi.org/project/nexorm/">
|
|
9
|
+
<img alt="Release" src="https://img.shields.io/badge/release-v0.1.0-f2c6c2?style=for-the-badge&labelColor=2f2d42">
|
|
10
|
+
</a>
|
|
11
|
+
<a href="https://github.com/Admin12121/nexorm/stargazers">
|
|
12
|
+
<img alt="Stars" src="https://img.shields.io/github/stars/Admin12121/nexorm?style=for-the-badge&labelColor=34364d&color=b8b8f3">
|
|
13
|
+
</a>
|
|
14
|
+
<a href="https://github.com/Admin12121/nexorm/issues">
|
|
15
|
+
<img alt="Issues" src="https://img.shields.io/github/issues/Admin12121/nexorm?style=for-the-badge&labelColor=34364d&color=f4a77c">
|
|
16
|
+
</a>
|
|
17
|
+
<a href="https://github.com/Admin12121/nexorm/graphs/contributors">
|
|
18
|
+
<img alt="Contributors" src="https://img.shields.io/github/contributors/Admin12121/nexorm?style=for-the-badge&labelColor=34364d&color=a7dc9a">
|
|
19
|
+
</a>
|
|
20
|
+
</p>
|
|
21
|
+
|
|
22
|
+
## Installation
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
pip install nexorm
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
For local development:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
python -m pip install -e ".[dev]"
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Quick Start
|
|
35
|
+
|
|
36
|
+
Initialize NexORM in your project:
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
nexorm init
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
This creates a local `manage.py` file and a `migrations/` directory:
|
|
43
|
+
|
|
44
|
+
```text
|
|
45
|
+
manage.py
|
|
46
|
+
migrations/
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
After that, you can use NexORM through `python manage.py`, similar to Django.
|
|
50
|
+
|
|
51
|
+
Define models in your app, for example `app/models.py`:
|
|
52
|
+
|
|
53
|
+
```python
|
|
54
|
+
from nexorm import ForeignKey, IntegerField, Model, StringField
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
class User(Model):
|
|
58
|
+
id = IntegerField(primary_key=True, auto_increment=True)
|
|
59
|
+
username = StringField(max_length=100, unique=True, index=True)
|
|
60
|
+
|
|
61
|
+
class Meta:
|
|
62
|
+
table_name = "users"
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
class Post(Model):
|
|
66
|
+
id = IntegerField(primary_key=True, auto_increment=True)
|
|
67
|
+
title = StringField(max_length=200)
|
|
68
|
+
user_id = ForeignKey("User", on_delete="CASCADE", related_name="posts")
|
|
69
|
+
|
|
70
|
+
class Meta:
|
|
71
|
+
table_name = "posts"
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Generate and apply migrations:
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
python manage.py makemigrations
|
|
78
|
+
python manage.py migrate
|
|
79
|
+
python manage.py showmigrations
|
|
80
|
+
python manage.py rollback
|
|
81
|
+
python manage.py sqlmigrate 0001_create_table_users.py
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
By default, `manage.py` uses `db.sqlite3` and imports models from `app.models`.
|
|
85
|
+
You can override both:
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
python manage.py --database local.sqlite3 --models myproject.models makemigrations
|
|
89
|
+
python manage.py --database local.sqlite3 --models myproject.models migrate
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Use the ORM:
|
|
93
|
+
|
|
94
|
+
```python
|
|
95
|
+
from nexorm import configure, transaction
|
|
96
|
+
from app.models import Post, User
|
|
97
|
+
|
|
98
|
+
configure("db.sqlite3")
|
|
99
|
+
|
|
100
|
+
user = User.objects.create(username="admin")
|
|
101
|
+
post = Post.objects.create(title="Hello", user_id=user.id)
|
|
102
|
+
|
|
103
|
+
same_user = User.objects.filter(username__contains="adm").first()
|
|
104
|
+
recent_posts = user.posts.order_by("-id").limit(10).all()
|
|
105
|
+
|
|
106
|
+
with transaction.atomic():
|
|
107
|
+
User.objects.create(username="vicky")
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
Use raw SQL only with parameters:
|
|
111
|
+
|
|
112
|
+
```python
|
|
113
|
+
user = User.objects.raw("SELECT * FROM users WHERE id = ?", [1]).first()
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Use with Flask:
|
|
117
|
+
|
|
118
|
+
```python
|
|
119
|
+
from flask import Flask
|
|
120
|
+
from nexorm import configure
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
def create_app():
|
|
124
|
+
configure("db.sqlite3")
|
|
125
|
+
app = Flask(__name__)
|
|
126
|
+
return app
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
## Models
|
|
130
|
+
|
|
131
|
+
Define models by subclassing `Model` and assigning field instances. If a model does not define a primary key, NexORM adds an auto-incrementing `id` field.
|
|
132
|
+
|
|
133
|
+
```python
|
|
134
|
+
from nexorm import BooleanField, DateTimeField, IntegerField, Model, StringField
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
class Article(Model):
|
|
138
|
+
title = StringField(max_length=180)
|
|
139
|
+
views = IntegerField(default=0)
|
|
140
|
+
published = BooleanField(default=False)
|
|
141
|
+
created_at = DateTimeField(nullable=True)
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
## Queries
|
|
145
|
+
|
|
146
|
+
```python
|
|
147
|
+
Post.objects.create(title="First post", user_id=1)
|
|
148
|
+
|
|
149
|
+
posts = Post.objects.filter(title__contains="First").order_by("-id").limit(10).all()
|
|
150
|
+
count = Post.objects.filter(user_id=1).count()
|
|
151
|
+
exists = Post.objects.filter(title="First post").exists()
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
Supported lookup suffixes include exact matching and common comparisons such as `gt`, `gte`, `lt`, `lte`, `contains`, `startswith`, `endswith`, and `in`.
|
|
155
|
+
|
|
156
|
+
## Multiple Databases
|
|
157
|
+
|
|
158
|
+
Configure the default connection:
|
|
159
|
+
|
|
160
|
+
```python
|
|
161
|
+
from nexorm import configure
|
|
162
|
+
|
|
163
|
+
configure("db.sqlite3")
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
Configure named connections:
|
|
167
|
+
|
|
168
|
+
```python
|
|
169
|
+
from nexorm import configure, transaction
|
|
170
|
+
from app.models import User
|
|
171
|
+
|
|
172
|
+
configure("db.sqlite3")
|
|
173
|
+
configure("analytics.sqlite3", alias="analytics")
|
|
174
|
+
|
|
175
|
+
admin = User.objects.create(username="admin")
|
|
176
|
+
report_user = User.objects.using("analytics").create(username="report")
|
|
177
|
+
|
|
178
|
+
analytics_users = User.objects.using("analytics").filter(username__contains="rep").all()
|
|
179
|
+
|
|
180
|
+
with transaction.atomic("analytics"):
|
|
181
|
+
User.objects.using("analytics").create(username="worker")
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
You can also pass a `Database` instance directly to `using(...)` or `transaction.atomic(...)`.
|
|
185
|
+
|
|
186
|
+
## Transactions
|
|
187
|
+
|
|
188
|
+
```python
|
|
189
|
+
from nexorm import transaction
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
with transaction.atomic():
|
|
193
|
+
Post.objects.create(title="Inside a transaction", user_id=1)
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
Nested transactions use SQLite savepoints.
|
|
197
|
+
|
|
198
|
+
## Migrations CLI
|
|
199
|
+
|
|
200
|
+
Initialize a project:
|
|
201
|
+
|
|
202
|
+
```bash
|
|
203
|
+
nexorm init
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
That command creates this local `manage.py` file:
|
|
207
|
+
|
|
208
|
+
```python
|
|
209
|
+
from nexorm.cli import main
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
if __name__ == "__main__":
|
|
213
|
+
main()
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
Generate and apply migrations:
|
|
217
|
+
|
|
218
|
+
```bash
|
|
219
|
+
python manage.py makemigrations
|
|
220
|
+
python manage.py migrate
|
|
221
|
+
python manage.py showmigrations
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
Other commands:
|
|
225
|
+
|
|
226
|
+
```bash
|
|
227
|
+
python manage.py rollback
|
|
228
|
+
python manage.py sqlmigrate 0001_initial.py
|
|
229
|
+
python manage.py dbshell
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
You can still use the installed `nexorm` command directly:
|
|
233
|
+
|
|
234
|
+
```bash
|
|
235
|
+
nexorm --database app.sqlite3 --models app.models makemigrations
|
|
236
|
+
nexorm --database app.sqlite3 --models app.models migrate
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
## Build
|
|
240
|
+
|
|
241
|
+
```bash
|
|
242
|
+
python -m pip install --upgrade build twine
|
|
243
|
+
python -m build
|
|
244
|
+
python -m twine check dist/*
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
## Publish to PyPI
|
|
248
|
+
|
|
249
|
+
Create an API token in PyPI, then upload manually:
|
|
250
|
+
|
|
251
|
+
```bash
|
|
252
|
+
python -m twine upload dist/*
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
When prompted:
|
|
256
|
+
|
|
257
|
+
```text
|
|
258
|
+
username: __token__
|
|
259
|
+
password: pypi-...
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
Use TestPyPI first if you want a dry run:
|
|
263
|
+
|
|
264
|
+
```bash
|
|
265
|
+
python -m twine upload --repository testpypi dist/*
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
## Status
|
|
269
|
+
|
|
270
|
+
NexORM is an early package. The current implementation focuses on SQLite and keeps the public API small: model fields, managers/querysets, raw queries, transactions, named connections, and file-based migrations.
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=69", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "nexorm"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "A minimal Django-style ORM for SQLite applications."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.10"
|
|
11
|
+
authors = [
|
|
12
|
+
{ name = "Admin12121" }
|
|
13
|
+
]
|
|
14
|
+
keywords = ["orm", "sqlite", "database", "migrations", "model"]
|
|
15
|
+
classifiers = [
|
|
16
|
+
"Development Status :: 3 - Alpha",
|
|
17
|
+
"Environment :: Console",
|
|
18
|
+
"Intended Audience :: Developers",
|
|
19
|
+
"Operating System :: OS Independent",
|
|
20
|
+
"Programming Language :: Python :: 3",
|
|
21
|
+
"Programming Language :: Python :: 3 :: Only",
|
|
22
|
+
"Programming Language :: Python :: 3.10",
|
|
23
|
+
"Programming Language :: Python :: 3.11",
|
|
24
|
+
"Programming Language :: Python :: 3.12",
|
|
25
|
+
"Programming Language :: Python :: 3.13",
|
|
26
|
+
"Topic :: Database",
|
|
27
|
+
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
28
|
+
]
|
|
29
|
+
dependencies = []
|
|
30
|
+
|
|
31
|
+
[project.optional-dependencies]
|
|
32
|
+
dev = [
|
|
33
|
+
"build>=1.2",
|
|
34
|
+
"pytest>=8",
|
|
35
|
+
"ruff>=0.5",
|
|
36
|
+
"twine>=5",
|
|
37
|
+
]
|
|
38
|
+
|
|
39
|
+
[project.urls]
|
|
40
|
+
Homepage = "https://github.com/Admin12121/nexorm"
|
|
41
|
+
Repository = "https://github.com/Admin12121/nexorm"
|
|
42
|
+
Issues = "https://github.com/Admin12121/nexorm/issues"
|
|
43
|
+
|
|
44
|
+
[project.scripts]
|
|
45
|
+
nexorm = "nexorm.cli:main"
|
|
46
|
+
|
|
47
|
+
[tool.setuptools.packages.find]
|
|
48
|
+
where = ["src"]
|
|
49
|
+
|
|
50
|
+
[tool.ruff]
|
|
51
|
+
line-length = 100
|
|
52
|
+
target-version = "py310"
|
|
53
|
+
|
|
54
|
+
[tool.pytest.ini_options]
|
|
55
|
+
pythonpath = ["src"]
|
|
56
|
+
testpaths = ["tests"]
|
nexorm-0.1.0/setup.cfg
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
from nexorm.database import Database, configure, default_db, get_connection
|
|
2
|
+
from nexorm.exceptions import DoesNotExist, IntegrityError, MultipleObjectsReturned, ValidationError
|
|
3
|
+
from nexorm.fields import (
|
|
4
|
+
BooleanField,
|
|
5
|
+
DateTimeField,
|
|
6
|
+
DecimalField,
|
|
7
|
+
Field,
|
|
8
|
+
FloatField,
|
|
9
|
+
ForeignKey,
|
|
10
|
+
IntegerField,
|
|
11
|
+
StringField,
|
|
12
|
+
TextField,
|
|
13
|
+
)
|
|
14
|
+
from nexorm.model import Model
|
|
15
|
+
from nexorm.transaction import transaction
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
__version__ = "0.1.0"
|
|
19
|
+
|
|
20
|
+
__all__ = [
|
|
21
|
+
"__version__",
|
|
22
|
+
"Model",
|
|
23
|
+
"Field",
|
|
24
|
+
"IntegerField",
|
|
25
|
+
"StringField",
|
|
26
|
+
"TextField",
|
|
27
|
+
"BooleanField",
|
|
28
|
+
"DateTimeField",
|
|
29
|
+
"FloatField",
|
|
30
|
+
"DecimalField",
|
|
31
|
+
"ForeignKey",
|
|
32
|
+
"configure",
|
|
33
|
+
"Database",
|
|
34
|
+
"default_db",
|
|
35
|
+
"get_connection",
|
|
36
|
+
"transaction",
|
|
37
|
+
"ValidationError",
|
|
38
|
+
"IntegrityError",
|
|
39
|
+
"DoesNotExist",
|
|
40
|
+
"MultipleObjectsReturned",
|
|
41
|
+
]
|