postgresdb3 0.4.0__tar.gz → 0.6.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 (30) hide show
  1. postgresdb3-0.6.0/PKG-INFO +251 -0
  2. postgresdb3-0.6.0/README.md +229 -0
  3. postgresdb3-0.6.0/postgresdb3/__init__.py +1 -0
  4. {postgresdb3-0.4.0/postgresdb3 → postgresdb3-0.6.0/postgresdb3/core}/async_db.py +1 -0
  5. {postgresdb3-0.4.0/postgresdb3 → postgresdb3-0.6.0/postgresdb3/core}/sync_db.py +1 -0
  6. postgresdb3-0.6.0/postgresdb3/orm/__init__.py +1 -0
  7. postgresdb3-0.6.0/postgresdb3/orm/base.py +91 -0
  8. postgresdb3-0.6.0/postgresdb3/orm/fields/__init__.py +6 -0
  9. postgresdb3-0.6.0/postgresdb3/orm/fields/base.py +37 -0
  10. postgresdb3-0.6.0/postgresdb3/orm/fields/datetime.py +17 -0
  11. postgresdb3-0.6.0/postgresdb3/orm/fields/misc.py +28 -0
  12. postgresdb3-0.6.0/postgresdb3/orm/fields/numeric.py +32 -0
  13. postgresdb3-0.6.0/postgresdb3/orm/fields/relations.py +16 -0
  14. postgresdb3-0.6.0/postgresdb3/orm/fields/text.py +15 -0
  15. postgresdb3-0.6.0/postgresdb3/orm/meta.py +41 -0
  16. postgresdb3-0.6.0/postgresdb3/orm/models.py +372 -0
  17. postgresdb3-0.6.0/postgresdb3/orm/query.py +283 -0
  18. postgresdb3-0.6.0/postgresdb3.egg-info/PKG-INFO +251 -0
  19. postgresdb3-0.6.0/postgresdb3.egg-info/SOURCES.txt +24 -0
  20. {postgresdb3-0.4.0 → postgresdb3-0.6.0}/setup.py +1 -1
  21. postgresdb3-0.4.0/PKG-INFO +0 -297
  22. postgresdb3-0.4.0/README.md +0 -275
  23. postgresdb3-0.4.0/postgresdb3.egg-info/PKG-INFO +0 -297
  24. postgresdb3-0.4.0/postgresdb3.egg-info/SOURCES.txt +0 -11
  25. {postgresdb3-0.4.0/postgresdb3 → postgresdb3-0.6.0/postgresdb3/core}/__init__.py +0 -0
  26. {postgresdb3-0.4.0 → postgresdb3-0.6.0}/postgresdb3.egg-info/dependency_links.txt +0 -0
  27. {postgresdb3-0.4.0 → postgresdb3-0.6.0}/postgresdb3.egg-info/requires.txt +0 -0
  28. {postgresdb3-0.4.0 → postgresdb3-0.6.0}/postgresdb3.egg-info/top_level.txt +0 -0
  29. {postgresdb3-0.4.0 → postgresdb3-0.6.0}/pyproject.toml +0 -0
  30. {postgresdb3-0.4.0 → postgresdb3-0.6.0}/setup.cfg +0 -0
@@ -0,0 +1,251 @@
1
+ Metadata-Version: 2.4
2
+ Name: postgresdb3
3
+ Version: 0.6.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
+ ![PyPI Version](https://img.shields.io/pypi/v/postgresdb3)
26
+ ![Python Version](https://img.shields.io/pypi/pyversions/postgresdb3)
27
+ ![License](https://img.shields.io/badge/license-MIT-green)
28
+
29
+ **PostgresDB3** — PostgreSQL bilan ishlash uchun oddiy, qulay va yengil Python wrapper.
30
+
31
+ Kutubxona quyidagilarni qo‘llab-quvvatlaydi:
32
+
33
+ - Sync va Async ishlash
34
+ - CRUD operatsiyalari
35
+ - Query builder (`where`, `join`, `group_by`, `order_by`, `limit`, `offset`)
36
+ - Kengaytirilgan filterlar (`gt`, `lt`, `like`, `ilike`, `in`, `isnull`)
37
+ - Raw SQL bajarish
38
+ - Sodda ORM tizimi
39
+
40
+ ---
41
+
42
+ # O‘rnatish
43
+
44
+ ```bash
45
+ pip install postgresdb3
46
+ ````
47
+
48
+ ---
49
+
50
+ # Sync foydalanish
51
+
52
+ ```python
53
+ from postgresdb3 import PostgresDB
54
+
55
+ db = PostgresDB(
56
+ database="mydb",
57
+ user="postgres",
58
+ password="mypassword"
59
+ )
60
+
61
+ # Jadval yaratish
62
+ db.create("users", "id SERIAL PRIMARY KEY, name VARCHAR(100), age INT")
63
+
64
+ # Qator qo‘shish
65
+ db.insert("users", "name, age", ("Ali", 25))
66
+
67
+ # Barcha ma'lumotlar
68
+ users = db.select("users")
69
+
70
+ # Shart bilan qidirish
71
+ adults = db.select("users", where={"age__gt": 18})
72
+
73
+ # Tartiblash
74
+ users = db.select("users", order_by="age DESC")
75
+
76
+ # Yangilash
77
+ db.update("users", "age", 26, "name", "Ali")
78
+
79
+ # O‘chirish
80
+ db.delete("users", "name", "Ali")
81
+
82
+ db.close()
83
+ ```
84
+
85
+ ---
86
+
87
+ # Async foydalanish
88
+
89
+ ```python
90
+ import asyncio
91
+ from postgresdb3 import AsyncPostgresDB
92
+
93
+ async def main():
94
+
95
+ db = AsyncPostgresDB(
96
+ database="mydb",
97
+ user="postgres",
98
+ password="mypassword"
99
+ )
100
+
101
+ await db.create("users", "id SERIAL PRIMARY KEY, name VARCHAR(100), age INT")
102
+
103
+ await db.insert("users", "name, age", ["Ali", 25])
104
+
105
+ users = await db.select("users")
106
+
107
+ adults = await db.select("users", where={"age__gt": 18})
108
+
109
+ await db.update("users", "age", 26, "name", "Ali")
110
+
111
+ await db.delete("users", "name", "Ali")
112
+
113
+ await db.close_pool()
114
+
115
+ asyncio.run(main())
116
+ ```
117
+
118
+ ---
119
+
120
+ # ORM foydalanish
121
+
122
+ PostgresDB3 oddiy ORM tizimini ham taqdim etadi.
123
+
124
+ ## Sync ORM
125
+
126
+ ```python
127
+ from postgresdb3 import PostgresDB
128
+ from postgresdb3.orm import Model
129
+ from postgresdb3.orm.fields import Serial, String, Integer
130
+
131
+ db = PostgresDB(
132
+ database="mydb",
133
+ user="postgres",
134
+ password="mypassword"
135
+ )
136
+
137
+ class User(Model):
138
+ db = db
139
+ table = "users"
140
+
141
+ id = Serial(primary_key=True)
142
+ name = String()
143
+ age = Integer()
144
+
145
+ User.create_table()
146
+
147
+ # create
148
+ user = User.create(name="Ali", age=20)
149
+
150
+ # all
151
+ users = User.all()
152
+
153
+ # find
154
+ user = User.find(1)
155
+
156
+ # filter
157
+ users = User.filter(age__gt=18).all()
158
+
159
+ # get
160
+ user = User.get(id=1)
161
+
162
+ # exclude
163
+ users = User.exclude(name="Ali").all()
164
+
165
+ # update
166
+ user.update(name="Valijon")
167
+
168
+ # delete
169
+ user.delete()
170
+ ```
171
+
172
+ ---
173
+
174
+ ## Async ORM
175
+
176
+ ```python
177
+ from postgresdb3 import AsyncPostgresDB
178
+ from postgresdb3.orm import AsyncModel
179
+ from postgresdb3.orm.fields import Serial, String, Integer
180
+
181
+ db = AsyncPostgresDB(
182
+ database="mydb",
183
+ user="postgres",
184
+ password="mypassword"
185
+ )
186
+
187
+ class User(AsyncModel):
188
+ db = db
189
+ table = "users"
190
+
191
+ id = Serial(primary_key=True)
192
+ name = String()
193
+ age = Integer()
194
+
195
+ await User.create_table()
196
+
197
+ user = await User.create(name="Ali", age=20)
198
+
199
+ users = await User.all()
200
+
201
+ user = await User.find(1)
202
+
203
+ users = await User.filter(age__gt=18).all()
204
+
205
+ user = await User.get(id=1)
206
+
207
+ users = await User.exclude(name="Ali").all()
208
+
209
+ await user.update(name="Valijon")
210
+
211
+ await user.delete()
212
+ ```
213
+
214
+ ---
215
+
216
+ # Filter operatorlari
217
+
218
+ | Operator | Tavsif |
219
+ | -------- | ---------------- |
220
+ | eq | teng |
221
+ | ne | teng emas |
222
+ | gt | katta |
223
+ | gte | katta yoki teng |
224
+ | lt | kichik |
225
+ | lte | kichik yoki teng |
226
+ | like | LIKE |
227
+ | ilike | ILIKE |
228
+ | in | IN |
229
+ | not_in | NOT IN |
230
+ | isnull | NULL tekshirish |
231
+
232
+ Misol:
233
+
234
+ ```python
235
+ User.filter(age__gt=18)
236
+ User.filter(name__ilike="%ali%")
237
+ User.filter(id__in=[1,2,3])
238
+ User.filter(name__ne="Ali")
239
+ ```
240
+
241
+ ---
242
+
243
+ # Raw SQL
244
+
245
+ ```python
246
+ result = db.raw(
247
+ "SELECT name FROM users WHERE age > %s",
248
+ [18],
249
+ fetchall=True
250
+ )
251
+ ```
@@ -0,0 +1,229 @@
1
+ # PostgresDB3
2
+
3
+ ![PyPI Version](https://img.shields.io/pypi/v/postgresdb3)
4
+ ![Python Version](https://img.shields.io/pypi/pyversions/postgresdb3)
5
+ ![License](https://img.shields.io/badge/license-MIT-green)
6
+
7
+ **PostgresDB3** — PostgreSQL bilan ishlash uchun oddiy, qulay va yengil Python wrapper.
8
+
9
+ Kutubxona quyidagilarni qo‘llab-quvvatlaydi:
10
+
11
+ - Sync va Async ishlash
12
+ - CRUD operatsiyalari
13
+ - Query builder (`where`, `join`, `group_by`, `order_by`, `limit`, `offset`)
14
+ - Kengaytirilgan filterlar (`gt`, `lt`, `like`, `ilike`, `in`, `isnull`)
15
+ - Raw SQL bajarish
16
+ - Sodda ORM tizimi
17
+
18
+ ---
19
+
20
+ # O‘rnatish
21
+
22
+ ```bash
23
+ pip install postgresdb3
24
+ ````
25
+
26
+ ---
27
+
28
+ # Sync foydalanish
29
+
30
+ ```python
31
+ from postgresdb3 import PostgresDB
32
+
33
+ db = PostgresDB(
34
+ database="mydb",
35
+ user="postgres",
36
+ password="mypassword"
37
+ )
38
+
39
+ # Jadval yaratish
40
+ db.create("users", "id SERIAL PRIMARY KEY, name VARCHAR(100), age INT")
41
+
42
+ # Qator qo‘shish
43
+ db.insert("users", "name, age", ("Ali", 25))
44
+
45
+ # Barcha ma'lumotlar
46
+ users = db.select("users")
47
+
48
+ # Shart bilan qidirish
49
+ adults = db.select("users", where={"age__gt": 18})
50
+
51
+ # Tartiblash
52
+ users = db.select("users", order_by="age DESC")
53
+
54
+ # Yangilash
55
+ db.update("users", "age", 26, "name", "Ali")
56
+
57
+ # O‘chirish
58
+ db.delete("users", "name", "Ali")
59
+
60
+ db.close()
61
+ ```
62
+
63
+ ---
64
+
65
+ # Async foydalanish
66
+
67
+ ```python
68
+ import asyncio
69
+ from postgresdb3 import AsyncPostgresDB
70
+
71
+ async def main():
72
+
73
+ db = AsyncPostgresDB(
74
+ database="mydb",
75
+ user="postgres",
76
+ password="mypassword"
77
+ )
78
+
79
+ await db.create("users", "id SERIAL PRIMARY KEY, name VARCHAR(100), age INT")
80
+
81
+ await db.insert("users", "name, age", ["Ali", 25])
82
+
83
+ users = await db.select("users")
84
+
85
+ adults = await db.select("users", where={"age__gt": 18})
86
+
87
+ await db.update("users", "age", 26, "name", "Ali")
88
+
89
+ await db.delete("users", "name", "Ali")
90
+
91
+ await db.close_pool()
92
+
93
+ asyncio.run(main())
94
+ ```
95
+
96
+ ---
97
+
98
+ # ORM foydalanish
99
+
100
+ PostgresDB3 oddiy ORM tizimini ham taqdim etadi.
101
+
102
+ ## Sync ORM
103
+
104
+ ```python
105
+ from postgresdb3 import PostgresDB
106
+ from postgresdb3.orm import Model
107
+ from postgresdb3.orm.fields import Serial, String, Integer
108
+
109
+ db = PostgresDB(
110
+ database="mydb",
111
+ user="postgres",
112
+ password="mypassword"
113
+ )
114
+
115
+ class User(Model):
116
+ db = db
117
+ table = "users"
118
+
119
+ id = Serial(primary_key=True)
120
+ name = String()
121
+ age = Integer()
122
+
123
+ User.create_table()
124
+
125
+ # create
126
+ user = User.create(name="Ali", age=20)
127
+
128
+ # all
129
+ users = User.all()
130
+
131
+ # find
132
+ user = User.find(1)
133
+
134
+ # filter
135
+ users = User.filter(age__gt=18).all()
136
+
137
+ # get
138
+ user = User.get(id=1)
139
+
140
+ # exclude
141
+ users = User.exclude(name="Ali").all()
142
+
143
+ # update
144
+ user.update(name="Valijon")
145
+
146
+ # delete
147
+ user.delete()
148
+ ```
149
+
150
+ ---
151
+
152
+ ## Async ORM
153
+
154
+ ```python
155
+ from postgresdb3 import AsyncPostgresDB
156
+ from postgresdb3.orm import AsyncModel
157
+ from postgresdb3.orm.fields import Serial, String, Integer
158
+
159
+ db = AsyncPostgresDB(
160
+ database="mydb",
161
+ user="postgres",
162
+ password="mypassword"
163
+ )
164
+
165
+ class User(AsyncModel):
166
+ db = db
167
+ table = "users"
168
+
169
+ id = Serial(primary_key=True)
170
+ name = String()
171
+ age = Integer()
172
+
173
+ await User.create_table()
174
+
175
+ user = await User.create(name="Ali", age=20)
176
+
177
+ users = await User.all()
178
+
179
+ user = await User.find(1)
180
+
181
+ users = await User.filter(age__gt=18).all()
182
+
183
+ user = await User.get(id=1)
184
+
185
+ users = await User.exclude(name="Ali").all()
186
+
187
+ await user.update(name="Valijon")
188
+
189
+ await user.delete()
190
+ ```
191
+
192
+ ---
193
+
194
+ # Filter operatorlari
195
+
196
+ | Operator | Tavsif |
197
+ | -------- | ---------------- |
198
+ | eq | teng |
199
+ | ne | teng emas |
200
+ | gt | katta |
201
+ | gte | katta yoki teng |
202
+ | lt | kichik |
203
+ | lte | kichik yoki teng |
204
+ | like | LIKE |
205
+ | ilike | ILIKE |
206
+ | in | IN |
207
+ | not_in | NOT IN |
208
+ | isnull | NULL tekshirish |
209
+
210
+ Misol:
211
+
212
+ ```python
213
+ User.filter(age__gt=18)
214
+ User.filter(name__ilike="%ali%")
215
+ User.filter(id__in=[1,2,3])
216
+ User.filter(name__ne="Ali")
217
+ ```
218
+
219
+ ---
220
+
221
+ # Raw SQL
222
+
223
+ ```python
224
+ result = db.raw(
225
+ "SELECT name FROM users WHERE age > %s",
226
+ [18],
227
+ fetchall=True
228
+ )
229
+ ```
@@ -0,0 +1 @@
1
+ from .core import PostgresDB, AsyncPostgresDB
@@ -165,6 +165,7 @@ class AsyncPostgresDB:
165
165
  operator_map = {
166
166
  "eq": "=",
167
167
  "ne": "!=",
168
+ "not": "!=",
168
169
  "gt": ">",
169
170
  "gte": ">=",
170
171
  "lt": "<",
@@ -241,6 +241,7 @@ class PostgresDB:
241
241
  operator_map = {
242
242
  "eq": "=",
243
243
  "ne": "!=",
244
+ "not": "!=",
244
245
  "gt": ">",
245
246
  "gte": ">=",
246
247
  "lt": "<",
@@ -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,17 @@
1
+ from .base import Field
2
+
3
+
4
+ class Date(Field):
5
+ sql_type = "DATE"
6
+
7
+
8
+ class Time(Field):
9
+ sql_type = "TIME"
10
+
11
+
12
+ class Timestamp(Field):
13
+ sql_type = "TIMESTAMP"
14
+
15
+
16
+ class Timestamptz(Field):
17
+ sql_type = "TIMESTAMPTZ"
@@ -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})"