postgresdb3 0.6.0__tar.gz → 1.0.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.
Files changed (39) hide show
  1. postgresdb3-1.0.0/PKG-INFO +298 -0
  2. postgresdb3-1.0.0/README.md +276 -0
  3. postgresdb3-1.0.0/postgresdb3/__init__.py +11 -0
  4. postgresdb3-1.0.0/postgresdb3/cli.py +62 -0
  5. {postgresdb3-0.6.0 → postgresdb3-1.0.0}/postgresdb3/core/async_db.py +220 -188
  6. {postgresdb3-0.6.0 → postgresdb3-1.0.0}/postgresdb3/core/sync_db.py +221 -247
  7. postgresdb3-1.0.0/postgresdb3/migrations/__init__.py +20 -0
  8. postgresdb3-1.0.0/postgresdb3/migrations/engine.py +241 -0
  9. {postgresdb3-0.6.0 → postgresdb3-1.0.0}/postgresdb3/orm/base.py +9 -2
  10. postgresdb3-1.0.0/postgresdb3/orm/expressions.py +80 -0
  11. {postgresdb3-0.6.0 → postgresdb3-1.0.0}/postgresdb3/orm/fields/__init__.py +2 -2
  12. postgresdb3-1.0.0/postgresdb3/orm/fields/datetime.py +32 -0
  13. postgresdb3-1.0.0/postgresdb3/orm/fields/foreign.py +61 -0
  14. {postgresdb3-0.6.0 → postgresdb3-1.0.0}/postgresdb3/orm/fields/numeric.py +6 -0
  15. postgresdb3-1.0.0/postgresdb3/orm/meta.py +117 -0
  16. {postgresdb3-0.6.0 → postgresdb3-1.0.0}/postgresdb3/orm/models.py +153 -50
  17. postgresdb3-1.0.0/postgresdb3/orm/query.py +696 -0
  18. postgresdb3-1.0.0/postgresdb3/orm/relations.py +196 -0
  19. postgresdb3-1.0.0/postgresdb3.egg-info/PKG-INFO +298 -0
  20. {postgresdb3-0.6.0 → postgresdb3-1.0.0}/postgresdb3.egg-info/SOURCES.txt +6 -1
  21. {postgresdb3-0.6.0 → postgresdb3-1.0.0}/setup.py +2 -2
  22. postgresdb3-0.6.0/PKG-INFO +0 -251
  23. postgresdb3-0.6.0/README.md +0 -229
  24. postgresdb3-0.6.0/postgresdb3/__init__.py +0 -1
  25. postgresdb3-0.6.0/postgresdb3/orm/fields/datetime.py +0 -17
  26. postgresdb3-0.6.0/postgresdb3/orm/fields/relations.py +0 -16
  27. postgresdb3-0.6.0/postgresdb3/orm/meta.py +0 -41
  28. postgresdb3-0.6.0/postgresdb3/orm/query.py +0 -283
  29. postgresdb3-0.6.0/postgresdb3.egg-info/PKG-INFO +0 -251
  30. {postgresdb3-0.6.0 → postgresdb3-1.0.0}/postgresdb3/core/__init__.py +0 -0
  31. {postgresdb3-0.6.0 → postgresdb3-1.0.0}/postgresdb3/orm/__init__.py +0 -0
  32. {postgresdb3-0.6.0 → postgresdb3-1.0.0}/postgresdb3/orm/fields/base.py +0 -0
  33. {postgresdb3-0.6.0 → postgresdb3-1.0.0}/postgresdb3/orm/fields/misc.py +0 -0
  34. {postgresdb3-0.6.0 → postgresdb3-1.0.0}/postgresdb3/orm/fields/text.py +0 -0
  35. {postgresdb3-0.6.0 → postgresdb3-1.0.0}/postgresdb3.egg-info/dependency_links.txt +0 -0
  36. {postgresdb3-0.6.0 → postgresdb3-1.0.0}/postgresdb3.egg-info/requires.txt +0 -0
  37. {postgresdb3-0.6.0 → postgresdb3-1.0.0}/postgresdb3.egg-info/top_level.txt +0 -0
  38. {postgresdb3-0.6.0 → postgresdb3-1.0.0}/pyproject.toml +0 -0
  39. {postgresdb3-0.6.0 → postgresdb3-1.0.0}/setup.cfg +0 -0
@@ -0,0 +1,298 @@
1
+ Metadata-Version: 2.4
2
+ Name: postgresdb3
3
+ Version: 1.0.0
4
+ Summary: High-Performance Sync and Async PostgreSQL ORM for Python
5
+ Author: Abdulbosit Alijonov
6
+ Project-URL: Source Code, https://github.com/AlijonovUz/PostgresDB
7
+ Classifier: Programming Language :: Python :: 3.9
8
+ Classifier: License :: OSI Approved :: MIT License
9
+ Classifier: Operating System :: OS Independent
10
+ Requires-Python: >=3.9
11
+ Description-Content-Type: text/markdown
12
+ Requires-Dist: psycopg2>=2.9
13
+ Requires-Dist: asyncpg>=0.31.0
14
+ Dynamic: author
15
+ Dynamic: classifier
16
+ Dynamic: description
17
+ Dynamic: description-content-type
18
+ Dynamic: project-url
19
+ Dynamic: requires-dist
20
+ Dynamic: requires-python
21
+ Dynamic: summary
22
+
23
+ # PostgresDB3 - High-Performance Python ORM
24
+
25
+ **PostgresDB3** — bu PostgreSQL uchun mo'ljallangan zamonaviy, tezkor va ham **sinxron**, ham **asinxron** ishlash imkoniyatiga ega bo'lgan ORM (Object-Relational Mapping) kutubxonasi.
26
+
27
+ U Django ORM kabi qulay va oson tushuniladi, lekin o'zida asinxronlik (`asyncpg`) va ko'plab yuqori texnologik xususiyatlarni mujassamlashtirgan. Kichik botlardan tortib, o'ta katta masshtabdagi (Highload) loyihalargacha bemalol ishlata olasiz!
28
+
29
+ ---
30
+
31
+ ## 📦 O'rnatish
32
+
33
+ Kutubxonani o'rnatish uchun terminalda quyidagi buyruqni kiriting:
34
+
35
+ ```bash
36
+ pip install postgresdb3
37
+ ```
38
+
39
+ ---
40
+
41
+ ## 🚀 Tezkor Boshlash
42
+
43
+ PostgresDB3 bir vaqtning o'zida ikkita dunyoni qo'llab-quvvatlaydi. Xohlasangiz **Sinxron**, xohlasangiz **Asinxron** loyihalarda bir xil sintaksis bilan ishlay olasiz.
44
+
45
+ ### 1. Ulanishni sozlash
46
+
47
+ ```python
48
+ from postgresdb3 import PostgresDB, AsyncPostgresDB
49
+
50
+ # Sinxron ulanish (psycopg2 asosida)
51
+ db_sync = PostgresDB("my_db", "user", "password", host="localhost", port=5432, echo=True)
52
+
53
+ # Asinxron ulanish (asyncpg asosida)
54
+ db_async = AsyncPostgresDB("my_db", "user", "password", host="localhost", port=5432, echo=True)
55
+ ```
56
+ *(Eslatma: `echo=True` yoqilsa, barcha bajarilayotgan SQL so'rovlar terminalda ko'rinib turadi, bu debug uchun juda foydali).*
57
+
58
+ ### 2. Modellarni Yaratish
59
+
60
+ ```python
61
+ from postgresdb3.orm.models import Model, AsyncModel
62
+ from postgresdb3 import String, Integer, Float
63
+
64
+ # Sinxron model
65
+ Model.db = db_sync
66
+
67
+ class User(Model):
68
+ name = String(length=50)
69
+ age = Integer(default=18)
70
+ score = Float(default=0.0)
71
+
72
+ # Asinxron model
73
+ AsyncModel.db = db_async
74
+
75
+ class AsyncUser(AsyncModel):
76
+ name = String(length=50)
77
+ age = Integer(default=18)
78
+ score = Float(default=0.0)
79
+
80
+ # Qo'shimcha sozlamalar (Murakkab Indekslar)
81
+ class Meta:
82
+ unique_together = (("name", "age"),) # Ism va yosh bir xil takrorlanmasligi kerak
83
+ index_together = (("score",),) # Qidiruvni tezlashtirish uchun index
84
+ ```
85
+
86
+ ### 3. CRUD (Yaratish, O'qish, Yangilash, O'chirish)
87
+
88
+ **Sinxron:**
89
+ ```python
90
+ # Yaratish
91
+ user = User.create(name="Ali", age=25)
92
+
93
+ # Barchasini olish
94
+ users = User.all()
95
+
96
+ # Qidirish
97
+ user = User.query().filter(name="Ali").first()
98
+
99
+ # Yangilash
100
+ user.score = 99.5
101
+ user.save()
102
+
103
+ # O'chirish
104
+ user.delete()
105
+ ```
106
+
107
+ **Asinxron:**
108
+ ```python
109
+ # Yaratish
110
+ user = await AsyncUser.create(name="Vali", age=22)
111
+
112
+ # Barchasini olish
113
+ users = await AsyncUser.all()
114
+
115
+ # Qidirish
116
+ user = await AsyncUser.query().filter(name="Vali").first()
117
+
118
+ # Yangilash
119
+ user.score = 100.0
120
+ await user.save()
121
+
122
+ # O'chirish
123
+ await user.delete()
124
+ ```
125
+
126
+ ### 4. Raw SQL dan Model Olish
127
+ Ba'zida juda murakkab yoki spesifik SQL yozishga to'g'ri keladi. Shunday paytda u oddiy `dict` emas, to'g'ridan to'g'ri Model obyekti bo'lib qaytishi kerak:
128
+
129
+ ```python
130
+ # Sinxron
131
+ users = User.raw_sql("SELECT * FROM users WHERE age > %s", 20)
132
+ print(users[0].name) # Bu Model Obyekti!
133
+
134
+ # Asinxron
135
+ users = await AsyncUser.raw_sql("SELECT * FROM asyncusers WHERE age > $1", 20)
136
+ ```
137
+
138
+ ---
139
+
140
+ ## 🔄 Migratsiya (Django uslubida)
141
+
142
+ Siz o'z loyihangiz papkasida bitta `manage.py` yaratib olib, jadvallarni SQL o'qib-o'tirmasdan terminal orqali avtomatik yangilab borishingiz mumkin.
143
+
144
+ **`manage.py` yaratamiz:**
145
+ ```python
146
+ import sys
147
+ from postgresdb3 import execute_from_command_line
148
+ from myapp.models import db_sync # Sizning bazaga ulangan db obyektingiz
149
+
150
+ if __name__ == "__main__":
151
+ execute_from_command_line(db_sync, sys.argv)
152
+ ```
153
+
154
+ **Terminalda:**
155
+ ```bash
156
+ # 1. Modellar asosida migratsiya faylini tayyorlash
157
+ python manage.py makemigrations initial_setup
158
+
159
+ # 2. Bazaga jadvallarni qo'shish
160
+ python manage.py migrate
161
+
162
+ # 3. Oxirgi migratsiyani bekor qilish va qaytarish (Rollback)
163
+ python manage.py undo
164
+ ```
165
+ *Tizim jadval qo'shish, ustunlarni o'zgartirish va `Meta` klassidagi indekslarni avtomatik o'zi hal qiladi! Xato qilsangiz, `undo` orqali bir soniyada hammasini orqaga qaytara olasiz.*
166
+
167
+ ---
168
+
169
+ ## 🔍 Murakkab Qidiruv va Filtrlar (Q va F)
170
+
171
+ **Q Obyekti (Murakkab shartlar - AND, OR):**
172
+ ```python
173
+ from postgresdb3 import Q
174
+
175
+ # OR (|) sharti
176
+ users = User.query().filter(Q(age__gt=20) | Q(name="Ali")).all()
177
+
178
+ # AND (&) sharti
179
+ users = User.query().filter(Q(age__lt=30) & Q(score__gt=50)).all()
180
+ ```
181
+
182
+ **F Obyekti (Ustunlarni bir-biriga solishtirish yoki yangilash):**
183
+ ```python
184
+ from postgresdb3 import F
185
+
186
+ # Yoshiga nisbatan score'i katta bo'lganlarni izlash
187
+ users = User.query().filter(score__gt=F("age")).all()
188
+
189
+ # Barchaning balini bazaning o'zida +10 ga oshirish
190
+ User.query().update(score=F("score") + 10)
191
+ ```
192
+
193
+ ---
194
+
195
+ ## 🔗 Aloqalar (Relations) va N+1 Yechimi
196
+
197
+ Loyiha `ForeignKey`, `OneToOneField` va `ManyToManyField` kabi turlarni to'liq qo'llab-quvvatlaydi.
198
+
199
+ ```python
200
+ from postgresdb3 import ForeignKey, ManyToManyField
201
+
202
+ class Post(Model):
203
+ title = String(length=100)
204
+ author = ForeignKey(User, related_name="posts")
205
+
206
+ class Tag(Model):
207
+ name = String(length=50)
208
+ posts = ManyToManyField(Post, related_name="tags")
209
+ ```
210
+
211
+ **N+1 xatoligini chetlab o'tish:**
212
+ Odatda chet el kalitlari bilan ishlaganda ko'plab ortiqcha so'rovlar yuzaga keladi. Bunga qarshi quyidagilardan foydalaning:
213
+
214
+ ```python
215
+ # ForeignKey uchun
216
+ posts = Post.query().select_related("author").all()
217
+ print(posts[0].author.name) # 1 ta SQL query bilan ish bitadi
218
+
219
+ # ManyToMany uchun
220
+ posts = Post.query().prefetch_related("tags").all()
221
+ for p in posts:
222
+ print(p.tags) # N+1 muammosi bo'lmaydi
223
+ ```
224
+
225
+ ---
226
+
227
+ ## 📊 Katta Ma'lumotlar bilan Ishlash (Bulk & Pagination)
228
+
229
+ **Ommaviy Yozish (Bulk Create):**
230
+ 10,000 ta obyekti birma-bir emas, bitta so'rov orqali kiritish:
231
+ ```python
232
+ users = [User(name=f"U-{i}", age=20) for i in range(10000)]
233
+ User.bulk_create(users)
234
+ ```
235
+
236
+ **Ommaviy Yangilash (Bulk Update):**
237
+ ```python
238
+ users = User.all()
239
+ for u in users:
240
+ u.age += 1
241
+ User.bulk_update(users, fields=["age"])
242
+ ```
243
+
244
+ **Sahifalash (Pagination):**
245
+ Foydalanuvchiga ma'lumotlarni qismlab (limit/offset bilan avtomatik) taqdim etish:
246
+ ```python
247
+ result = User.query().paginate(page=1, per_page=20)
248
+ print(result["total"]) # Jami elementlar soni
249
+ print(result["pages"]) # Jami sahifalar soni
250
+ print(result["has_next"]) # Keyingi sahifa bormi? (True/False)
251
+ print(result["data"]) # Modellar ro'yxati (20 ta)
252
+ ```
253
+
254
+ ---
255
+
256
+ ## 🛡 Tranzaksiyalar (Xavfsizlik)
257
+
258
+ Muhim operatsiyalar (masalan, pul o'tkazish) vaqtida xato yuz bersa, barcha qilingan ishlarni avtomatik bekor qilish (Rollback):
259
+
260
+ **Sinxron:**
261
+ ```python
262
+ with db_sync.transaction():
263
+ user1.score -= 50
264
+ user1.save()
265
+ user2.score += 50
266
+ user2.save()
267
+ # Agar shu joyda qandaydir xatolik chiqsa, hech qaysi userning puli yechilmaydi!
268
+ ```
269
+
270
+ **Asinxron:**
271
+ ```python
272
+ async with db_async.transaction():
273
+ user1.score -= 50
274
+ await user1.save()
275
+ user2.score += 50
276
+ await user2.save()
277
+ ```
278
+
279
+ ---
280
+
281
+ ## 📈 Agregatsiya (Sum, Avg, Min, Max, Count)
282
+
283
+ Baza orqali kalkulyatsiyalarni amalga oshirish:
284
+
285
+ ```python
286
+ from postgresdb3 import Sum, Avg, Max
287
+
288
+ result = User.query().aggregate(
289
+ total_score=Sum("score"),
290
+ avg_age=Avg("age"),
291
+ max_score=Max("score")
292
+ )
293
+ print(result) # {'total_score': 1500, 'avg_age': 25, 'max_score': 100}
294
+ ```
295
+
296
+ ---
297
+
298
+ *Ushbu ORM kutubxonasi tezlik va xavfsizlikni birinchi o'ringa qoyuvchi mutaxassislar uchun maxsus qurilgan. Mazza qilib foydalaning!*
@@ -0,0 +1,276 @@
1
+ # PostgresDB3 - High-Performance Python ORM
2
+
3
+ **PostgresDB3** — bu PostgreSQL uchun mo'ljallangan zamonaviy, tezkor va ham **sinxron**, ham **asinxron** ishlash imkoniyatiga ega bo'lgan ORM (Object-Relational Mapping) kutubxonasi.
4
+
5
+ U Django ORM kabi qulay va oson tushuniladi, lekin o'zida asinxronlik (`asyncpg`) va ko'plab yuqori texnologik xususiyatlarni mujassamlashtirgan. Kichik botlardan tortib, o'ta katta masshtabdagi (Highload) loyihalargacha bemalol ishlata olasiz!
6
+
7
+ ---
8
+
9
+ ## 📦 O'rnatish
10
+
11
+ Kutubxonani o'rnatish uchun terminalda quyidagi buyruqni kiriting:
12
+
13
+ ```bash
14
+ pip install postgresdb3
15
+ ```
16
+
17
+ ---
18
+
19
+ ## 🚀 Tezkor Boshlash
20
+
21
+ PostgresDB3 bir vaqtning o'zida ikkita dunyoni qo'llab-quvvatlaydi. Xohlasangiz **Sinxron**, xohlasangiz **Asinxron** loyihalarda bir xil sintaksis bilan ishlay olasiz.
22
+
23
+ ### 1. Ulanishni sozlash
24
+
25
+ ```python
26
+ from postgresdb3 import PostgresDB, AsyncPostgresDB
27
+
28
+ # Sinxron ulanish (psycopg2 asosida)
29
+ db_sync = PostgresDB("my_db", "user", "password", host="localhost", port=5432, echo=True)
30
+
31
+ # Asinxron ulanish (asyncpg asosida)
32
+ db_async = AsyncPostgresDB("my_db", "user", "password", host="localhost", port=5432, echo=True)
33
+ ```
34
+ *(Eslatma: `echo=True` yoqilsa, barcha bajarilayotgan SQL so'rovlar terminalda ko'rinib turadi, bu debug uchun juda foydali).*
35
+
36
+ ### 2. Modellarni Yaratish
37
+
38
+ ```python
39
+ from postgresdb3.orm.models import Model, AsyncModel
40
+ from postgresdb3 import String, Integer, Float
41
+
42
+ # Sinxron model
43
+ Model.db = db_sync
44
+
45
+ class User(Model):
46
+ name = String(length=50)
47
+ age = Integer(default=18)
48
+ score = Float(default=0.0)
49
+
50
+ # Asinxron model
51
+ AsyncModel.db = db_async
52
+
53
+ class AsyncUser(AsyncModel):
54
+ name = String(length=50)
55
+ age = Integer(default=18)
56
+ score = Float(default=0.0)
57
+
58
+ # Qo'shimcha sozlamalar (Murakkab Indekslar)
59
+ class Meta:
60
+ unique_together = (("name", "age"),) # Ism va yosh bir xil takrorlanmasligi kerak
61
+ index_together = (("score",),) # Qidiruvni tezlashtirish uchun index
62
+ ```
63
+
64
+ ### 3. CRUD (Yaratish, O'qish, Yangilash, O'chirish)
65
+
66
+ **Sinxron:**
67
+ ```python
68
+ # Yaratish
69
+ user = User.create(name="Ali", age=25)
70
+
71
+ # Barchasini olish
72
+ users = User.all()
73
+
74
+ # Qidirish
75
+ user = User.query().filter(name="Ali").first()
76
+
77
+ # Yangilash
78
+ user.score = 99.5
79
+ user.save()
80
+
81
+ # O'chirish
82
+ user.delete()
83
+ ```
84
+
85
+ **Asinxron:**
86
+ ```python
87
+ # Yaratish
88
+ user = await AsyncUser.create(name="Vali", age=22)
89
+
90
+ # Barchasini olish
91
+ users = await AsyncUser.all()
92
+
93
+ # Qidirish
94
+ user = await AsyncUser.query().filter(name="Vali").first()
95
+
96
+ # Yangilash
97
+ user.score = 100.0
98
+ await user.save()
99
+
100
+ # O'chirish
101
+ await user.delete()
102
+ ```
103
+
104
+ ### 4. Raw SQL dan Model Olish
105
+ Ba'zida juda murakkab yoki spesifik SQL yozishga to'g'ri keladi. Shunday paytda u oddiy `dict` emas, to'g'ridan to'g'ri Model obyekti bo'lib qaytishi kerak:
106
+
107
+ ```python
108
+ # Sinxron
109
+ users = User.raw_sql("SELECT * FROM users WHERE age > %s", 20)
110
+ print(users[0].name) # Bu Model Obyekti!
111
+
112
+ # Asinxron
113
+ users = await AsyncUser.raw_sql("SELECT * FROM asyncusers WHERE age > $1", 20)
114
+ ```
115
+
116
+ ---
117
+
118
+ ## 🔄 Migratsiya (Django uslubida)
119
+
120
+ Siz o'z loyihangiz papkasida bitta `manage.py` yaratib olib, jadvallarni SQL o'qib-o'tirmasdan terminal orqali avtomatik yangilab borishingiz mumkin.
121
+
122
+ **`manage.py` yaratamiz:**
123
+ ```python
124
+ import sys
125
+ from postgresdb3 import execute_from_command_line
126
+ from myapp.models import db_sync # Sizning bazaga ulangan db obyektingiz
127
+
128
+ if __name__ == "__main__":
129
+ execute_from_command_line(db_sync, sys.argv)
130
+ ```
131
+
132
+ **Terminalda:**
133
+ ```bash
134
+ # 1. Modellar asosida migratsiya faylini tayyorlash
135
+ python manage.py makemigrations initial_setup
136
+
137
+ # 2. Bazaga jadvallarni qo'shish
138
+ python manage.py migrate
139
+
140
+ # 3. Oxirgi migratsiyani bekor qilish va qaytarish (Rollback)
141
+ python manage.py undo
142
+ ```
143
+ *Tizim jadval qo'shish, ustunlarni o'zgartirish va `Meta` klassidagi indekslarni avtomatik o'zi hal qiladi! Xato qilsangiz, `undo` orqali bir soniyada hammasini orqaga qaytara olasiz.*
144
+
145
+ ---
146
+
147
+ ## 🔍 Murakkab Qidiruv va Filtrlar (Q va F)
148
+
149
+ **Q Obyekti (Murakkab shartlar - AND, OR):**
150
+ ```python
151
+ from postgresdb3 import Q
152
+
153
+ # OR (|) sharti
154
+ users = User.query().filter(Q(age__gt=20) | Q(name="Ali")).all()
155
+
156
+ # AND (&) sharti
157
+ users = User.query().filter(Q(age__lt=30) & Q(score__gt=50)).all()
158
+ ```
159
+
160
+ **F Obyekti (Ustunlarni bir-biriga solishtirish yoki yangilash):**
161
+ ```python
162
+ from postgresdb3 import F
163
+
164
+ # Yoshiga nisbatan score'i katta bo'lganlarni izlash
165
+ users = User.query().filter(score__gt=F("age")).all()
166
+
167
+ # Barchaning balini bazaning o'zida +10 ga oshirish
168
+ User.query().update(score=F("score") + 10)
169
+ ```
170
+
171
+ ---
172
+
173
+ ## 🔗 Aloqalar (Relations) va N+1 Yechimi
174
+
175
+ Loyiha `ForeignKey`, `OneToOneField` va `ManyToManyField` kabi turlarni to'liq qo'llab-quvvatlaydi.
176
+
177
+ ```python
178
+ from postgresdb3 import ForeignKey, ManyToManyField
179
+
180
+ class Post(Model):
181
+ title = String(length=100)
182
+ author = ForeignKey(User, related_name="posts")
183
+
184
+ class Tag(Model):
185
+ name = String(length=50)
186
+ posts = ManyToManyField(Post, related_name="tags")
187
+ ```
188
+
189
+ **N+1 xatoligini chetlab o'tish:**
190
+ Odatda chet el kalitlari bilan ishlaganda ko'plab ortiqcha so'rovlar yuzaga keladi. Bunga qarshi quyidagilardan foydalaning:
191
+
192
+ ```python
193
+ # ForeignKey uchun
194
+ posts = Post.query().select_related("author").all()
195
+ print(posts[0].author.name) # 1 ta SQL query bilan ish bitadi
196
+
197
+ # ManyToMany uchun
198
+ posts = Post.query().prefetch_related("tags").all()
199
+ for p in posts:
200
+ print(p.tags) # N+1 muammosi bo'lmaydi
201
+ ```
202
+
203
+ ---
204
+
205
+ ## 📊 Katta Ma'lumotlar bilan Ishlash (Bulk & Pagination)
206
+
207
+ **Ommaviy Yozish (Bulk Create):**
208
+ 10,000 ta obyekti birma-bir emas, bitta so'rov orqali kiritish:
209
+ ```python
210
+ users = [User(name=f"U-{i}", age=20) for i in range(10000)]
211
+ User.bulk_create(users)
212
+ ```
213
+
214
+ **Ommaviy Yangilash (Bulk Update):**
215
+ ```python
216
+ users = User.all()
217
+ for u in users:
218
+ u.age += 1
219
+ User.bulk_update(users, fields=["age"])
220
+ ```
221
+
222
+ **Sahifalash (Pagination):**
223
+ Foydalanuvchiga ma'lumotlarni qismlab (limit/offset bilan avtomatik) taqdim etish:
224
+ ```python
225
+ result = User.query().paginate(page=1, per_page=20)
226
+ print(result["total"]) # Jami elementlar soni
227
+ print(result["pages"]) # Jami sahifalar soni
228
+ print(result["has_next"]) # Keyingi sahifa bormi? (True/False)
229
+ print(result["data"]) # Modellar ro'yxati (20 ta)
230
+ ```
231
+
232
+ ---
233
+
234
+ ## 🛡 Tranzaksiyalar (Xavfsizlik)
235
+
236
+ Muhim operatsiyalar (masalan, pul o'tkazish) vaqtida xato yuz bersa, barcha qilingan ishlarni avtomatik bekor qilish (Rollback):
237
+
238
+ **Sinxron:**
239
+ ```python
240
+ with db_sync.transaction():
241
+ user1.score -= 50
242
+ user1.save()
243
+ user2.score += 50
244
+ user2.save()
245
+ # Agar shu joyda qandaydir xatolik chiqsa, hech qaysi userning puli yechilmaydi!
246
+ ```
247
+
248
+ **Asinxron:**
249
+ ```python
250
+ async with db_async.transaction():
251
+ user1.score -= 50
252
+ await user1.save()
253
+ user2.score += 50
254
+ await user2.save()
255
+ ```
256
+
257
+ ---
258
+
259
+ ## 📈 Agregatsiya (Sum, Avg, Min, Max, Count)
260
+
261
+ Baza orqali kalkulyatsiyalarni amalga oshirish:
262
+
263
+ ```python
264
+ from postgresdb3 import Sum, Avg, Max
265
+
266
+ result = User.query().aggregate(
267
+ total_score=Sum("score"),
268
+ avg_age=Avg("age"),
269
+ max_score=Max("score")
270
+ )
271
+ print(result) # {'total_score': 1500, 'avg_age': 25, 'max_score': 100}
272
+ ```
273
+
274
+ ---
275
+
276
+ *Ushbu ORM kutubxonasi tezlik va xavfsizlikni birinchi o'ringa qoyuvchi mutaxassislar uchun maxsus qurilgan. Mazza qilib foydalaning!*
@@ -0,0 +1,11 @@
1
+ from .core import PostgresDB, AsyncPostgresDB
2
+ from .migrations.engine import MigrationEngine
3
+ from .orm.expressions import Q, F, Sum, Avg, Min, Max, Count
4
+ from .orm.fields import (
5
+ String, Integer, Boolean, Float, Double, Decimal,
6
+ Date, Time, Timestamp, Timestamptz,
7
+ JSON, JSONB, UUID, Array,
8
+ ForeignKey, OneToOneField, ManyToManyField,
9
+ Serial, BigSerial, SmallInteger, BigInteger, Text
10
+ )
11
+ from .cli import execute_from_command_line
@@ -0,0 +1,62 @@
1
+ import sys
2
+ import argparse
3
+ import asyncio
4
+ from .migrations.engine import MigrationEngine
5
+ from .core import PostgresDB, AsyncPostgresDB
6
+
7
+
8
+ def execute_from_command_line(db, argv=None):
9
+ """
10
+ Kutubxonadan foydalanuvchilar o'z loyihalarida terminal buyruqlarini
11
+ ishga tushirishi uchun maxsus CLI funksiyasi (xuddi Django manage.py kabi).
12
+ """
13
+ if argv is None:
14
+ argv = sys.argv
15
+
16
+ parser = argparse.ArgumentParser(description="PostgresDB CLI - Ma'lumotlar bazasini boshqarish")
17
+ subparsers = parser.add_subparsers(dest="command", help="Mavjud buyruqlar")
18
+
19
+
20
+ make_parser = subparsers.add_parser("makemigrations", help="Modellardagi o'zgarishlar asosida yangi migratsiya fayllarini yaratadi")
21
+ make_parser.add_argument("name", nargs="?", default="auto", help="Migratsiya nomi (masalan: initial_setup)")
22
+
23
+
24
+ subparsers.add_parser("migrate", help="Mavjud migratsiyalarni ma'lumotlar bazasiga qo'llaydi")
25
+ subparsers.add_parser("undo", help="Oxirgi migratsiyani bekor qiladi va bazadan o'chiradi")
26
+
27
+ args = parser.parse_args(argv[1:])
28
+
29
+ if args.command == "makemigrations":
30
+ engine = MigrationEngine()
31
+ print(f"'{args.name}' nomli migratsiya yaratilmoqda...")
32
+ engine.makemigrations(args.name)
33
+
34
+ elif args.command == "migrate":
35
+ engine = MigrationEngine()
36
+ if isinstance(db, PostgresDB):
37
+ engine.migrate(db)
38
+ elif isinstance(db, AsyncPostgresDB):
39
+
40
+ loop = asyncio.get_event_loop()
41
+ if loop.is_running():
42
+ asyncio.ensure_future(engine.async_migrate(db))
43
+ else:
44
+ loop.run_until_complete(engine.async_migrate(db))
45
+ else:
46
+ print("Xato: Noma'lum DB obyekti (PostgresDB yoki AsyncPostgresDB kerak).")
47
+
48
+ elif args.command == "undo":
49
+ engine = MigrationEngine()
50
+ if isinstance(db, PostgresDB):
51
+ engine.undo_migration(db)
52
+ elif isinstance(db, AsyncPostgresDB):
53
+ loop = asyncio.get_event_loop()
54
+ if loop.is_running():
55
+ asyncio.ensure_future(engine.async_undo_migration(db))
56
+ else:
57
+ loop.run_until_complete(engine.async_undo_migration(db))
58
+ else:
59
+ print("Xato: Noma'lum DB obyekti (PostgresDB yoki AsyncPostgresDB kerak).")
60
+
61
+ else:
62
+ parser.print_help()