postgresdb3 0.4.0__tar.gz → 0.5.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.
- postgresdb3-0.5.0/PKG-INFO +255 -0
- postgresdb3-0.5.0/README.md +233 -0
- postgresdb3-0.5.0/postgresdb3/__init__.py +1 -0
- postgresdb3-0.5.0/postgresdb3/orm/__init__.py +1 -0
- postgresdb3-0.5.0/postgresdb3/orm/base.py +91 -0
- postgresdb3-0.5.0/postgresdb3/orm/fields/__init__.py +6 -0
- postgresdb3-0.5.0/postgresdb3/orm/fields/base.py +37 -0
- postgresdb3-0.5.0/postgresdb3/orm/fields/datetime.py +17 -0
- postgresdb3-0.5.0/postgresdb3/orm/fields/misc.py +28 -0
- postgresdb3-0.5.0/postgresdb3/orm/fields/numeric.py +32 -0
- postgresdb3-0.5.0/postgresdb3/orm/fields/relations.py +16 -0
- postgresdb3-0.5.0/postgresdb3/orm/fields/text.py +15 -0
- postgresdb3-0.5.0/postgresdb3/orm/meta.py +41 -0
- postgresdb3-0.5.0/postgresdb3/orm/models.py +276 -0
- postgresdb3-0.5.0/postgresdb3/orm/query.py +119 -0
- postgresdb3-0.5.0/postgresdb3.egg-info/PKG-INFO +255 -0
- postgresdb3-0.5.0/postgresdb3.egg-info/SOURCES.txt +24 -0
- {postgresdb3-0.4.0 → postgresdb3-0.5.0}/setup.py +1 -1
- postgresdb3-0.4.0/PKG-INFO +0 -297
- postgresdb3-0.4.0/README.md +0 -275
- postgresdb3-0.4.0/postgresdb3.egg-info/PKG-INFO +0 -297
- postgresdb3-0.4.0/postgresdb3.egg-info/SOURCES.txt +0 -11
- {postgresdb3-0.4.0/postgresdb3 → postgresdb3-0.5.0/postgresdb3/core}/__init__.py +0 -0
- {postgresdb3-0.4.0/postgresdb3 → postgresdb3-0.5.0/postgresdb3/core}/async_db.py +0 -0
- {postgresdb3-0.4.0/postgresdb3 → postgresdb3-0.5.0/postgresdb3/core}/sync_db.py +0 -0
- {postgresdb3-0.4.0 → postgresdb3-0.5.0}/postgresdb3.egg-info/dependency_links.txt +0 -0
- {postgresdb3-0.4.0 → postgresdb3-0.5.0}/postgresdb3.egg-info/requires.txt +0 -0
- {postgresdb3-0.4.0 → postgresdb3-0.5.0}/postgresdb3.egg-info/top_level.txt +0 -0
- {postgresdb3-0.4.0 → postgresdb3-0.5.0}/pyproject.toml +0 -0
- {postgresdb3-0.4.0 → postgresdb3-0.5.0}/setup.cfg +0 -0
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: postgresdb3
|
|
3
|
+
Version: 0.5.0
|
|
4
|
+
Summary: Python uchun oddiy PostgreSQL wrapper
|
|
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
|
|
24
|
+
|
|
25
|
+

|
|
26
|
+

|
|
27
|
+

|
|
28
|
+
|
|
29
|
+
**PostgresDB3** — PostgreSQL bilan ishlash uchun oddiy, qulay va yengil Python wrapper.
|
|
30
|
+
Kutubxona sync va async ishlashni qo‘llab-quvvatlaydi hamda sodda ORM imkoniyatlarini ham taqdim etadi.
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
# O‘rnatish
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
pip install postgresdb3
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
# Asosiy imkoniyatlar
|
|
43
|
+
|
|
44
|
+
* PostgreSQL bilan **sync va async** ishlash
|
|
45
|
+
* CRUD amallari
|
|
46
|
+
* `where`, `join`, `group_by`, `order_by`, `limit`, `offset`
|
|
47
|
+
* `like`, `ilike`, `in`, `isnull`, `gt`, `lt` kabi filterlar
|
|
48
|
+
* Raw SQL bajarish imkoniyati
|
|
49
|
+
* Sodda ORM tizimi
|
|
50
|
+
* Async ORM qo‘llab-quvvatlash
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
# Sync foydalanish
|
|
55
|
+
|
|
56
|
+
```python
|
|
57
|
+
from postgresdb3 import PostgresDB
|
|
58
|
+
|
|
59
|
+
db = PostgresDB(
|
|
60
|
+
database="mydb",
|
|
61
|
+
user="postgres",
|
|
62
|
+
password="mypassword",
|
|
63
|
+
host="localhost",
|
|
64
|
+
port=5432
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
# Jadval yaratish
|
|
68
|
+
db.create("users", "id SERIAL PRIMARY KEY, name VARCHAR(100), age INT")
|
|
69
|
+
|
|
70
|
+
# Bitta qator qo‘shish
|
|
71
|
+
db.insert("users", "name, age", ("Ali", 25))
|
|
72
|
+
|
|
73
|
+
# Bir nechta qator qo‘shish
|
|
74
|
+
db.insert_many(
|
|
75
|
+
"users",
|
|
76
|
+
"name, age",
|
|
77
|
+
[("Vali", 30), ("Gulnoza", 22), ("Hasan", 28)]
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
# Barcha ma'lumotlarni olish
|
|
81
|
+
users = db.select("users")
|
|
82
|
+
print(users)
|
|
83
|
+
|
|
84
|
+
# Faqat kerakli ustunlarni olish
|
|
85
|
+
users = db.select("users", columns=["id", "name"])
|
|
86
|
+
print(users)
|
|
87
|
+
|
|
88
|
+
# Bitta qatorni olish
|
|
89
|
+
user = db.select("users", where={"name": "Ali"}, fetchone=True)
|
|
90
|
+
print(user)
|
|
91
|
+
|
|
92
|
+
# Shart bilan qidirish
|
|
93
|
+
adults = db.select("users", where={"age__gt": 18})
|
|
94
|
+
print(adults)
|
|
95
|
+
|
|
96
|
+
# LIKE qidiruv
|
|
97
|
+
users_like = db.select("users", where={"name__like": "%Ali%"})
|
|
98
|
+
print(users_like)
|
|
99
|
+
|
|
100
|
+
# ILIKE qidiruv
|
|
101
|
+
users_ilike = db.select("users", where={"name__ilike": "%ali%"})
|
|
102
|
+
print(users_ilike)
|
|
103
|
+
|
|
104
|
+
# IN operatori
|
|
105
|
+
selected_users = db.select("users", where={"id__in": [1, 2, 3]})
|
|
106
|
+
print(selected_users)
|
|
107
|
+
|
|
108
|
+
# NULL tekshirish
|
|
109
|
+
users_with_name = db.select("users", where={"name__isnull": False})
|
|
110
|
+
print(users_with_name)
|
|
111
|
+
|
|
112
|
+
# Tartiblash va limit
|
|
113
|
+
ordered_users = db.select(
|
|
114
|
+
"users",
|
|
115
|
+
where={"age__gt": 18},
|
|
116
|
+
order_by="age DESC",
|
|
117
|
+
limit=2
|
|
118
|
+
)
|
|
119
|
+
print(ordered_users)
|
|
120
|
+
|
|
121
|
+
# Pagination
|
|
122
|
+
paged_users = db.select(
|
|
123
|
+
"users",
|
|
124
|
+
order_by="id ASC",
|
|
125
|
+
limit=2,
|
|
126
|
+
offset=2
|
|
127
|
+
)
|
|
128
|
+
print(paged_users)
|
|
129
|
+
|
|
130
|
+
# Ma'lumotni yangilash
|
|
131
|
+
db.update("users", "age", 26, "name", "Ali")
|
|
132
|
+
|
|
133
|
+
# Ma'lumotni o‘chirish
|
|
134
|
+
db.delete("users", "name", "Ali")
|
|
135
|
+
|
|
136
|
+
# Jadvalni o‘chirish
|
|
137
|
+
db.drop("users", cascade=False)
|
|
138
|
+
|
|
139
|
+
# Raw SQL bajarish
|
|
140
|
+
result = db.raw("SELECT name, age FROM users WHERE age > %s", [25], fetchall=True)
|
|
141
|
+
print(result)
|
|
142
|
+
|
|
143
|
+
# Connectionni yopish
|
|
144
|
+
db.close()
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
---
|
|
148
|
+
|
|
149
|
+
# Async foydalanish
|
|
150
|
+
|
|
151
|
+
```python
|
|
152
|
+
import asyncio
|
|
153
|
+
from postgresdb3 import AsyncPostgresDB
|
|
154
|
+
|
|
155
|
+
async def main():
|
|
156
|
+
db = AsyncPostgresDB(
|
|
157
|
+
database="mydb",
|
|
158
|
+
user="postgres",
|
|
159
|
+
password="mypassword",
|
|
160
|
+
host="localhost",
|
|
161
|
+
port=5432
|
|
162
|
+
)
|
|
163
|
+
|
|
164
|
+
await db.create("users", "id SERIAL PRIMARY KEY, name VARCHAR(100), age INT")
|
|
165
|
+
|
|
166
|
+
await db.insert("users", "name, age", ["Ali", 25])
|
|
167
|
+
|
|
168
|
+
await db.insert_many(
|
|
169
|
+
"users",
|
|
170
|
+
"name, age",
|
|
171
|
+
[["Vali", 30], ["Gulnoza", 22], ["Hasan", 28]]
|
|
172
|
+
)
|
|
173
|
+
|
|
174
|
+
users = await db.select("users")
|
|
175
|
+
print(users)
|
|
176
|
+
|
|
177
|
+
user = await db.select("users", where={"name": "Ali"}, fetchone=True)
|
|
178
|
+
print(user)
|
|
179
|
+
|
|
180
|
+
adults = await db.select("users", where={"age__gt": 18})
|
|
181
|
+
print(adults)
|
|
182
|
+
|
|
183
|
+
users_ilike = await db.select("users", where={"name__ilike": "%ali%"})
|
|
184
|
+
print(users_ilike)
|
|
185
|
+
|
|
186
|
+
await db.update("users", "age", 26, "name", "Ali")
|
|
187
|
+
|
|
188
|
+
await db.delete("users", "name", "Ali")
|
|
189
|
+
|
|
190
|
+
await db.drop("users", cascade=False)
|
|
191
|
+
|
|
192
|
+
result = await db.raw(
|
|
193
|
+
"SELECT name, age FROM users WHERE age > $1",
|
|
194
|
+
[25],
|
|
195
|
+
fetchall=True
|
|
196
|
+
)
|
|
197
|
+
|
|
198
|
+
print(result)
|
|
199
|
+
|
|
200
|
+
await db.close_pool()
|
|
201
|
+
|
|
202
|
+
asyncio.run(main())
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
---
|
|
206
|
+
|
|
207
|
+
# ORM foydalanish
|
|
208
|
+
|
|
209
|
+
## Sync ORM
|
|
210
|
+
|
|
211
|
+
```python
|
|
212
|
+
from postgresdb3 import PostgresDB
|
|
213
|
+
from postgresdb3.orm import Model
|
|
214
|
+
from postgresdb3.orm.fields import Serial, String, Integer, Text
|
|
215
|
+
|
|
216
|
+
db = PostgresDB(
|
|
217
|
+
database="mydb",
|
|
218
|
+
user="postgres",
|
|
219
|
+
password="mypassword"
|
|
220
|
+
)
|
|
221
|
+
|
|
222
|
+
class User(Model):
|
|
223
|
+
db = db
|
|
224
|
+
table = "users"
|
|
225
|
+
|
|
226
|
+
id = Serial(primary_key=True)
|
|
227
|
+
name = String()
|
|
228
|
+
age = Integer()
|
|
229
|
+
about = Text(nullable=True)
|
|
230
|
+
|
|
231
|
+
User.create_table()
|
|
232
|
+
|
|
233
|
+
user = User.create(name="Ali", age=20)
|
|
234
|
+
|
|
235
|
+
print(User.all())
|
|
236
|
+
|
|
237
|
+
user = User.find(1)
|
|
238
|
+
|
|
239
|
+
user.update(name="Valijon")
|
|
240
|
+
|
|
241
|
+
user.delete()
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
---
|
|
245
|
+
|
|
246
|
+
# Qo‘shimcha
|
|
247
|
+
|
|
248
|
+
`%s` va `$1` bilan parametrizatsiya qilish xavfsiz va SQL injection'dan himoya qiladi.
|
|
249
|
+
|
|
250
|
+
`where` va `join` yordamida murakkab so‘rovlar yozish mumkin.
|
|
251
|
+
|
|
252
|
+
`limit`, `offset` va `order_by` parametrlaridan foydalanib ma'lumotlarni tartiblash va sahifalash oson.
|
|
253
|
+
|
|
254
|
+
`raw()` metodi orqali kerak bo‘lganda to‘g‘ridan-to‘g‘ri SQL so‘rov yozish mumkin.
|
|
255
|
+
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
# PostgresDB3
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+

|
|
5
|
+

|
|
6
|
+
|
|
7
|
+
**PostgresDB3** — PostgreSQL bilan ishlash uchun oddiy, qulay va yengil Python wrapper.
|
|
8
|
+
Kutubxona sync va async ishlashni qo‘llab-quvvatlaydi hamda sodda ORM imkoniyatlarini ham taqdim etadi.
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# O‘rnatish
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
pip install postgresdb3
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
# Asosiy imkoniyatlar
|
|
21
|
+
|
|
22
|
+
* PostgreSQL bilan **sync va async** ishlash
|
|
23
|
+
* CRUD amallari
|
|
24
|
+
* `where`, `join`, `group_by`, `order_by`, `limit`, `offset`
|
|
25
|
+
* `like`, `ilike`, `in`, `isnull`, `gt`, `lt` kabi filterlar
|
|
26
|
+
* Raw SQL bajarish imkoniyati
|
|
27
|
+
* Sodda ORM tizimi
|
|
28
|
+
* Async ORM qo‘llab-quvvatlash
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
# Sync foydalanish
|
|
33
|
+
|
|
34
|
+
```python
|
|
35
|
+
from postgresdb3 import PostgresDB
|
|
36
|
+
|
|
37
|
+
db = PostgresDB(
|
|
38
|
+
database="mydb",
|
|
39
|
+
user="postgres",
|
|
40
|
+
password="mypassword",
|
|
41
|
+
host="localhost",
|
|
42
|
+
port=5432
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
# Jadval yaratish
|
|
46
|
+
db.create("users", "id SERIAL PRIMARY KEY, name VARCHAR(100), age INT")
|
|
47
|
+
|
|
48
|
+
# Bitta qator qo‘shish
|
|
49
|
+
db.insert("users", "name, age", ("Ali", 25))
|
|
50
|
+
|
|
51
|
+
# Bir nechta qator qo‘shish
|
|
52
|
+
db.insert_many(
|
|
53
|
+
"users",
|
|
54
|
+
"name, age",
|
|
55
|
+
[("Vali", 30), ("Gulnoza", 22), ("Hasan", 28)]
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
# Barcha ma'lumotlarni olish
|
|
59
|
+
users = db.select("users")
|
|
60
|
+
print(users)
|
|
61
|
+
|
|
62
|
+
# Faqat kerakli ustunlarni olish
|
|
63
|
+
users = db.select("users", columns=["id", "name"])
|
|
64
|
+
print(users)
|
|
65
|
+
|
|
66
|
+
# Bitta qatorni olish
|
|
67
|
+
user = db.select("users", where={"name": "Ali"}, fetchone=True)
|
|
68
|
+
print(user)
|
|
69
|
+
|
|
70
|
+
# Shart bilan qidirish
|
|
71
|
+
adults = db.select("users", where={"age__gt": 18})
|
|
72
|
+
print(adults)
|
|
73
|
+
|
|
74
|
+
# LIKE qidiruv
|
|
75
|
+
users_like = db.select("users", where={"name__like": "%Ali%"})
|
|
76
|
+
print(users_like)
|
|
77
|
+
|
|
78
|
+
# ILIKE qidiruv
|
|
79
|
+
users_ilike = db.select("users", where={"name__ilike": "%ali%"})
|
|
80
|
+
print(users_ilike)
|
|
81
|
+
|
|
82
|
+
# IN operatori
|
|
83
|
+
selected_users = db.select("users", where={"id__in": [1, 2, 3]})
|
|
84
|
+
print(selected_users)
|
|
85
|
+
|
|
86
|
+
# NULL tekshirish
|
|
87
|
+
users_with_name = db.select("users", where={"name__isnull": False})
|
|
88
|
+
print(users_with_name)
|
|
89
|
+
|
|
90
|
+
# Tartiblash va limit
|
|
91
|
+
ordered_users = db.select(
|
|
92
|
+
"users",
|
|
93
|
+
where={"age__gt": 18},
|
|
94
|
+
order_by="age DESC",
|
|
95
|
+
limit=2
|
|
96
|
+
)
|
|
97
|
+
print(ordered_users)
|
|
98
|
+
|
|
99
|
+
# Pagination
|
|
100
|
+
paged_users = db.select(
|
|
101
|
+
"users",
|
|
102
|
+
order_by="id ASC",
|
|
103
|
+
limit=2,
|
|
104
|
+
offset=2
|
|
105
|
+
)
|
|
106
|
+
print(paged_users)
|
|
107
|
+
|
|
108
|
+
# Ma'lumotni yangilash
|
|
109
|
+
db.update("users", "age", 26, "name", "Ali")
|
|
110
|
+
|
|
111
|
+
# Ma'lumotni o‘chirish
|
|
112
|
+
db.delete("users", "name", "Ali")
|
|
113
|
+
|
|
114
|
+
# Jadvalni o‘chirish
|
|
115
|
+
db.drop("users", cascade=False)
|
|
116
|
+
|
|
117
|
+
# Raw SQL bajarish
|
|
118
|
+
result = db.raw("SELECT name, age FROM users WHERE age > %s", [25], fetchall=True)
|
|
119
|
+
print(result)
|
|
120
|
+
|
|
121
|
+
# Connectionni yopish
|
|
122
|
+
db.close()
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
---
|
|
126
|
+
|
|
127
|
+
# Async foydalanish
|
|
128
|
+
|
|
129
|
+
```python
|
|
130
|
+
import asyncio
|
|
131
|
+
from postgresdb3 import AsyncPostgresDB
|
|
132
|
+
|
|
133
|
+
async def main():
|
|
134
|
+
db = AsyncPostgresDB(
|
|
135
|
+
database="mydb",
|
|
136
|
+
user="postgres",
|
|
137
|
+
password="mypassword",
|
|
138
|
+
host="localhost",
|
|
139
|
+
port=5432
|
|
140
|
+
)
|
|
141
|
+
|
|
142
|
+
await db.create("users", "id SERIAL PRIMARY KEY, name VARCHAR(100), age INT")
|
|
143
|
+
|
|
144
|
+
await db.insert("users", "name, age", ["Ali", 25])
|
|
145
|
+
|
|
146
|
+
await db.insert_many(
|
|
147
|
+
"users",
|
|
148
|
+
"name, age",
|
|
149
|
+
[["Vali", 30], ["Gulnoza", 22], ["Hasan", 28]]
|
|
150
|
+
)
|
|
151
|
+
|
|
152
|
+
users = await db.select("users")
|
|
153
|
+
print(users)
|
|
154
|
+
|
|
155
|
+
user = await db.select("users", where={"name": "Ali"}, fetchone=True)
|
|
156
|
+
print(user)
|
|
157
|
+
|
|
158
|
+
adults = await db.select("users", where={"age__gt": 18})
|
|
159
|
+
print(adults)
|
|
160
|
+
|
|
161
|
+
users_ilike = await db.select("users", where={"name__ilike": "%ali%"})
|
|
162
|
+
print(users_ilike)
|
|
163
|
+
|
|
164
|
+
await db.update("users", "age", 26, "name", "Ali")
|
|
165
|
+
|
|
166
|
+
await db.delete("users", "name", "Ali")
|
|
167
|
+
|
|
168
|
+
await db.drop("users", cascade=False)
|
|
169
|
+
|
|
170
|
+
result = await db.raw(
|
|
171
|
+
"SELECT name, age FROM users WHERE age > $1",
|
|
172
|
+
[25],
|
|
173
|
+
fetchall=True
|
|
174
|
+
)
|
|
175
|
+
|
|
176
|
+
print(result)
|
|
177
|
+
|
|
178
|
+
await db.close_pool()
|
|
179
|
+
|
|
180
|
+
asyncio.run(main())
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
---
|
|
184
|
+
|
|
185
|
+
# ORM foydalanish
|
|
186
|
+
|
|
187
|
+
## Sync ORM
|
|
188
|
+
|
|
189
|
+
```python
|
|
190
|
+
from postgresdb3 import PostgresDB
|
|
191
|
+
from postgresdb3.orm import Model
|
|
192
|
+
from postgresdb3.orm.fields import Serial, String, Integer, Text
|
|
193
|
+
|
|
194
|
+
db = PostgresDB(
|
|
195
|
+
database="mydb",
|
|
196
|
+
user="postgres",
|
|
197
|
+
password="mypassword"
|
|
198
|
+
)
|
|
199
|
+
|
|
200
|
+
class User(Model):
|
|
201
|
+
db = db
|
|
202
|
+
table = "users"
|
|
203
|
+
|
|
204
|
+
id = Serial(primary_key=True)
|
|
205
|
+
name = String()
|
|
206
|
+
age = Integer()
|
|
207
|
+
about = Text(nullable=True)
|
|
208
|
+
|
|
209
|
+
User.create_table()
|
|
210
|
+
|
|
211
|
+
user = User.create(name="Ali", age=20)
|
|
212
|
+
|
|
213
|
+
print(User.all())
|
|
214
|
+
|
|
215
|
+
user = User.find(1)
|
|
216
|
+
|
|
217
|
+
user.update(name="Valijon")
|
|
218
|
+
|
|
219
|
+
user.delete()
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
---
|
|
223
|
+
|
|
224
|
+
# Qo‘shimcha
|
|
225
|
+
|
|
226
|
+
`%s` va `$1` bilan parametrizatsiya qilish xavfsiz va SQL injection'dan himoya qiladi.
|
|
227
|
+
|
|
228
|
+
`where` va `join` yordamida murakkab so‘rovlar yozish mumkin.
|
|
229
|
+
|
|
230
|
+
`limit`, `offset` va `order_by` parametrlaridan foydalanib ma'lumotlarni tartiblash va sahifalash oson.
|
|
231
|
+
|
|
232
|
+
`raw()` metodi orqali kerak bo‘lganda to‘g‘ridan-to‘g‘ri SQL so‘rov yozish mumkin.
|
|
233
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .core import PostgresDB, AsyncPostgresDB
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .models import Model, AsyncModel
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
class BaseModel:
|
|
2
|
+
db = None
|
|
3
|
+
table = None
|
|
4
|
+
pk = "id"
|
|
5
|
+
_fields = {}
|
|
6
|
+
|
|
7
|
+
def __init__(self, **kwargs):
|
|
8
|
+
for field_name in self._fields:
|
|
9
|
+
setattr(self, field_name, kwargs.get(field_name))
|
|
10
|
+
|
|
11
|
+
for key, value in kwargs.items():
|
|
12
|
+
if key not in self._fields:
|
|
13
|
+
setattr(self, key, value)
|
|
14
|
+
|
|
15
|
+
def __iter__(self):
|
|
16
|
+
for field in self._fields:
|
|
17
|
+
yield field, getattr(self, field, None)
|
|
18
|
+
|
|
19
|
+
def __getitem__(self, item):
|
|
20
|
+
return getattr(self, item)
|
|
21
|
+
|
|
22
|
+
@classmethod
|
|
23
|
+
def _check_setup(cls):
|
|
24
|
+
if cls.db is None:
|
|
25
|
+
raise ValueError(f"{cls.__name__}.db belgilanmagan")
|
|
26
|
+
|
|
27
|
+
if cls.table is None:
|
|
28
|
+
raise ValueError(f"{cls.__name__}.table belgilanmagan")
|
|
29
|
+
|
|
30
|
+
if not isinstance(cls._fields, dict):
|
|
31
|
+
raise ValueError(f"{cls.__name__}._fields noto‘g‘ri")
|
|
32
|
+
|
|
33
|
+
@classmethod
|
|
34
|
+
def _from_record(cls, record):
|
|
35
|
+
if record is None:
|
|
36
|
+
return None
|
|
37
|
+
|
|
38
|
+
if isinstance(record, dict):
|
|
39
|
+
return cls(**record)
|
|
40
|
+
|
|
41
|
+
if hasattr(record, "_asdict"):
|
|
42
|
+
return cls(**record._asdict())
|
|
43
|
+
|
|
44
|
+
if hasattr(record, "items"):
|
|
45
|
+
return cls(**dict(record))
|
|
46
|
+
|
|
47
|
+
if isinstance(record, (tuple, list)):
|
|
48
|
+
data = dict(zip(cls._fields.keys(), record))
|
|
49
|
+
return cls(**data)
|
|
50
|
+
|
|
51
|
+
data = {}
|
|
52
|
+
for field_name in cls._fields:
|
|
53
|
+
try:
|
|
54
|
+
if hasattr(record, field_name):
|
|
55
|
+
data[field_name] = getattr(record, field_name)
|
|
56
|
+
else:
|
|
57
|
+
data[field_name] = record[field_name]
|
|
58
|
+
except Exception:
|
|
59
|
+
pass
|
|
60
|
+
|
|
61
|
+
return cls(**data)
|
|
62
|
+
|
|
63
|
+
@classmethod
|
|
64
|
+
def _from_records(cls, records):
|
|
65
|
+
if not records:
|
|
66
|
+
return []
|
|
67
|
+
return [cls._from_record(record) for record in records]
|
|
68
|
+
|
|
69
|
+
@classmethod
|
|
70
|
+
def get_fields(cls):
|
|
71
|
+
return cls._fields
|
|
72
|
+
|
|
73
|
+
@classmethod
|
|
74
|
+
def get_pk_name(cls):
|
|
75
|
+
for name, field in cls._fields.items():
|
|
76
|
+
if getattr(field, "primary_key", False):
|
|
77
|
+
return name
|
|
78
|
+
return cls.pk
|
|
79
|
+
|
|
80
|
+
def to_dict(self):
|
|
81
|
+
return {
|
|
82
|
+
field_name: getattr(self, field_name, None)
|
|
83
|
+
for field_name in self._fields
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
def __repr__(self):
|
|
87
|
+
fields = ", ".join(
|
|
88
|
+
f"{name}={getattr(self, name, None)!r}"
|
|
89
|
+
for name in self._fields
|
|
90
|
+
)
|
|
91
|
+
return f"<{self.__class__.__name__} {fields}>"
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
from .base import Field
|
|
2
|
+
from .numeric import Integer, BigInteger, SmallInteger, Serial, BigSerial, Decimal
|
|
3
|
+
from .text import String, Text
|
|
4
|
+
from .datetime import Date, Time, Timestamp, Timestamptz
|
|
5
|
+
from .misc import Boolean, JSON, JSONB, UUID, Array
|
|
6
|
+
from .relations import ForeignKey
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
class Field:
|
|
2
|
+
|
|
3
|
+
sql_type = ""
|
|
4
|
+
|
|
5
|
+
def __init__(
|
|
6
|
+
self,
|
|
7
|
+
*,
|
|
8
|
+
nullable=False,
|
|
9
|
+
primary_key=False,
|
|
10
|
+
unique=False,
|
|
11
|
+
default=None,
|
|
12
|
+
index=False
|
|
13
|
+
):
|
|
14
|
+
self.nullable = nullable
|
|
15
|
+
self.primary_key = primary_key
|
|
16
|
+
self.unique = unique
|
|
17
|
+
self.default = default
|
|
18
|
+
self.index = index
|
|
19
|
+
self.name = None
|
|
20
|
+
|
|
21
|
+
def to_sql(self):
|
|
22
|
+
|
|
23
|
+
parts = [self.name, self.sql_type]
|
|
24
|
+
|
|
25
|
+
if self.primary_key:
|
|
26
|
+
parts.append("PRIMARY KEY")
|
|
27
|
+
|
|
28
|
+
if self.unique:
|
|
29
|
+
parts.append("UNIQUE")
|
|
30
|
+
|
|
31
|
+
if not self.nullable and not self.primary_key:
|
|
32
|
+
parts.append("NOT NULL")
|
|
33
|
+
|
|
34
|
+
if self.default is not None:
|
|
35
|
+
parts.append(f"DEFAULT {self.default}")
|
|
36
|
+
|
|
37
|
+
return " ".join(parts)
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
from .base import Field
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class Boolean(Field):
|
|
5
|
+
sql_type = "BOOLEAN"
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class JSON(Field):
|
|
9
|
+
sql_type = "JSON"
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class JSONB(Field):
|
|
13
|
+
sql_type = "JSONB"
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class UUID(Field):
|
|
17
|
+
sql_type = "UUID"
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class Array(Field):
|
|
21
|
+
|
|
22
|
+
def __init__(self, base_type, **kwargs):
|
|
23
|
+
super().__init__(**kwargs)
|
|
24
|
+
self.base_type = base_type
|
|
25
|
+
|
|
26
|
+
@property
|
|
27
|
+
def sql_type(self):
|
|
28
|
+
return f"{self.base_type}[]"
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
from .base import Field
|
|
2
|
+
|
|
3
|
+
class Integer(Field):
|
|
4
|
+
sql_type = "INTEGER"
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class BigInteger(Field):
|
|
8
|
+
sql_type = "BIGINT"
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class SmallInteger(Field):
|
|
12
|
+
sql_type = "SMALLINT"
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class Serial(Field):
|
|
16
|
+
sql_type = "SERIAL"
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class BigSerial(Field):
|
|
20
|
+
sql_type = "BIGSERIAL"
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class Decimal(Field):
|
|
24
|
+
|
|
25
|
+
def __init__(self, precision=10, scale=2, **kwargs):
|
|
26
|
+
super().__init__(**kwargs)
|
|
27
|
+
self.precision = precision
|
|
28
|
+
self.scale = scale
|
|
29
|
+
|
|
30
|
+
@property
|
|
31
|
+
def sql_type(self):
|
|
32
|
+
return f"NUMERIC({self.precision},{self.scale})"
|