postgresdb3 0.2.2__tar.gz → 0.3.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.
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: postgresdb3
3
- Version: 0.2.2
3
+ Version: 0.3.0
4
4
  Summary: Python uchun oddiy PostgreSQL wrapper
5
- Home-page: https://github.com/AlijonovUz/PostgresDB
6
5
  Author: Abdulbosit Alijonov
6
+ Project-URL: Source Code, https://github.com/AlijonovUz/PostgresDB
7
7
  Classifier: Programming Language :: Python :: 3
8
8
  Classifier: License :: OSI Approved :: MIT License
9
9
  Classifier: Operating System :: OS Independent
@@ -15,7 +15,7 @@ Dynamic: author
15
15
  Dynamic: classifier
16
16
  Dynamic: description
17
17
  Dynamic: description-content-type
18
- Dynamic: home-page
18
+ Dynamic: project-url
19
19
  Dynamic: requires-dist
20
20
  Dynamic: requires-python
21
21
  Dynamic: summary
@@ -31,7 +31,7 @@ Oddiy va qulay Python wrapper PostgreSQL bazasi bilan ishlash uchun.
31
31
  ## O'rnatish
32
32
 
33
33
  ``` bash
34
- pip install postgresdb3
34
+ pip install postgresdb3
35
35
  ```
36
36
 
37
37
  ## Foydalanish (Sync)
@@ -9,7 +9,7 @@ Oddiy va qulay Python wrapper PostgreSQL bazasi bilan ishlash uchun.
9
9
  ## O'rnatish
10
10
 
11
11
  ``` bash
12
- pip install postgresdb3
12
+ pip install postgresdb3
13
13
  ```
14
14
 
15
15
  ## Foydalanish (Sync)
@@ -11,7 +11,7 @@ class AsyncPostgresDB:
11
11
  Aiogram kabi async frameworklar bilan to‘g‘ridan-to‘g‘ri ishlash uchun mos.
12
12
  """
13
13
 
14
- def __init__(self, database: str, user: str, password: str, host: str = "localhost", port: int = 5432):
14
+ def __init__(self, database: str, user: str, password: str, host: str = "localhost", port: int = 5432) -> None:
15
15
  """
16
16
  PostgreSQL bazasiga ulanishni tayyorlaydi.
17
17
 
@@ -29,7 +29,7 @@ class AsyncPostgresDB:
29
29
  self.port = port
30
30
  self.pool: Optional[asyncpg.pool.Pool] = None
31
31
 
32
- async def manager(self, sql: str, *params, fetchone=False, fetchall=False, commit=False):
32
+ async def _manager(self, sql: str, *params, fetchone=False, fetchall=False, commit=False) -> Any:
33
33
  """
34
34
  Markaziy metod: barcha SQL so‘rovlarni bajaradi.
35
35
 
@@ -63,7 +63,7 @@ class AsyncPostgresDB:
63
63
  if fetchall:
64
64
  return await conn.fetch(sql, *params)
65
65
 
66
- async def close_pool(self):
66
+ async def close_pool(self) -> None:
67
67
  """
68
68
  Connection poolni yopadi.
69
69
  """
@@ -71,7 +71,7 @@ class AsyncPostgresDB:
71
71
  await self.pool.close()
72
72
  self.pool = None
73
73
 
74
- async def create(self, table: str, columns: str):
74
+ async def create(self, table: str, columns: str) -> None:
75
75
  """
76
76
  Jadval yaratadi (agar mavjud bo‘lsa o‘tkazib yuboradi).
77
77
 
@@ -79,26 +79,26 @@ class AsyncPostgresDB:
79
79
  table (str): Jadval nomi.
80
80
  columns (str): Ustunlar va turlari, misol: "id SERIAL PRIMARY KEY, name TEXT".
81
81
  """
82
- await self.manager(f"CREATE TABLE IF NOT EXISTS {table} ({columns})", commit=True)
82
+ await self._manager(f"CREATE TABLE IF NOT EXISTS {table} ({columns})", commit=True)
83
83
 
84
- async def drop(self, table: str):
84
+ async def drop(self, table: str) -> None:
85
85
  """
86
86
  Jadvalni o‘chiradi (agar mavjud bo‘lsa).
87
87
 
88
88
  Args:
89
89
  table (str): Jadval nomi.
90
90
  """
91
- await self.manager(f"DROP TABLE IF EXISTS {table} CASCADE", commit=True)
91
+ await self._manager(f"DROP TABLE IF EXISTS {table} CASCADE", commit=True)
92
92
 
93
93
  async def select(
94
- self, table: str, columns: str = "*",
95
- where: Optional[List[Any]] = None,
96
- join: Optional[List[tuple]] = None,
97
- group_by: Optional[str] = None,
98
- order_by: Optional[str] = None,
99
- limit: Optional[int] = None,
100
- fetchone: bool = False
101
- ):
94
+ self, table: str, columns: str = "*",
95
+ where: Optional[List[Any]] = None,
96
+ join: Optional[List[tuple]] = None,
97
+ group_by: Optional[str] = None,
98
+ order_by: Optional[str] = None,
99
+ limit: Optional[int] = None,
100
+ fetchone: bool = False
101
+ ) -> Any:
102
102
  """
103
103
  Jadvaldan ma'lumotlarni tanlash.
104
104
 
@@ -137,9 +137,9 @@ class AsyncPostgresDB:
137
137
  sql += f" LIMIT $%d" % (len(params) + 1)
138
138
  params.append(limit)
139
139
 
140
- return await self.manager(sql, *params, fetchone=fetchone, fetchall=not fetchone)
140
+ return await self._manager(sql, *params, fetchone=fetchone, fetchall=not fetchone)
141
141
 
142
- async def insert(self, table: str, columns: str, values: List[Any]):
142
+ async def insert(self, table: str, columns: str, values: List[Any]) -> None:
143
143
  """
144
144
  Jadvalga yangi qator qo‘shadi.
145
145
 
@@ -148,11 +148,52 @@ class AsyncPostgresDB:
148
148
  columns (str): Ustunlar nomi, misol: "name, age".
149
149
  values (List[Any]): Qiymatlar, misol: ["Ali", 25].
150
150
  """
151
- placeholders = ", ".join(f"${i+1}" for i in range(len(values)))
151
+ placeholders = ", ".join(f"${i + 1}" for i in range(len(values)))
152
152
  sql = f"INSERT INTO {table} ({columns}) VALUES ({placeholders})"
153
- await self.manager(sql, *values, commit=True)
153
+ await self._manager(sql, *values, commit=True)
154
154
 
155
- async def update(self, table: str, set_column: str, set_value: Any, where_column: str, where_value: Any):
155
+ async def insert_many(self, table: str, columns: str, values_list: List[List[Any]]) -> None:
156
+ """
157
+ Jadvalga bir nechta qator qo‘shish (bulk insert).
158
+
159
+ Args:
160
+ table (str): Jadval nomi.
161
+ columns (str): Ustunlar nomi, misol: "name, age".
162
+ values_list (List[List[Any]]): Qiymatlar ro‘yxati, misol: [["Ali", 25], ["Vali", 30]].
163
+
164
+ Raises:
165
+ ValueError: Agar `values_list` bo‘sh bo‘lsa.
166
+
167
+ Notes:
168
+ - `asyncpg` kutubxonasida har bir parametr uchun unikal `$n` indekslari kerak,
169
+ shuning uchun har bir qator uchun ketma-ket `$1, $2, ...` ishlatiladi.
170
+ - Metod barcha qatorlarni bir so‘rovda qo‘shadi.
171
+ - `fetchmany` kerak emas, chunki bu insert operatsiyasi natija qaytarmaydi.
172
+
173
+ Example:
174
+ await db.insert_many(
175
+ "users",
176
+ "name, age",
177
+ [["Ali", 25], ["Vali", 30], ["Guli", 22]]
178
+ )
179
+ """
180
+ if not values_list:
181
+ raise ValueError("values_list bo'sh bo'lishi mumkin emas")
182
+
183
+ placeholders_list = []
184
+ flat_values = []
185
+ counter = 1
186
+
187
+ for values in values_list:
188
+ placeholders = ", ".join(f"${i}" for i in range(counter, counter + len(values)))
189
+ placeholders_list.append(f"({placeholders})")
190
+ flat_values.extend(values)
191
+ counter += len(values)
192
+
193
+ sql = f"INSERT INTO {table} ({columns}) VALUES {', '.join(placeholders_list)}"
194
+ await self._manager(sql, *flat_values, commit=True)
195
+
196
+ async def update(self, table: str, set_column: str, set_value: Any, where_column: str, where_value: Any) -> None:
156
197
  """
157
198
  Jadvaldagi qatorni yangilaydi.
158
199
 
@@ -164,9 +205,9 @@ class AsyncPostgresDB:
164
205
  where_value (Any): Filtrlash qiymati.
165
206
  """
166
207
  sql = f"UPDATE {table} SET {set_column} = $1 WHERE {where_column} = $2"
167
- await self.manager(sql, set_value, where_value, commit=True)
208
+ await self._manager(sql, set_value, where_value, commit=True)
168
209
 
169
- async def delete(self, table: str, where_column: str, where_value: Any):
210
+ async def delete(self, table: str, where_column: str, where_value: Any) -> None:
170
211
  """
171
212
  Jadvaldan qator o‘chiradi.
172
213
 
@@ -176,7 +217,7 @@ class AsyncPostgresDB:
176
217
  where_value (Any): Filtrlash qiymati.
177
218
  """
178
219
  sql = f"DELETE FROM {table} WHERE {where_column} = $1"
179
- await self.manager(sql, where_value, commit=True)
220
+ await self._manager(sql, where_value, commit=True)
180
221
 
181
222
  async def list_tables(self, schema: str = "public") -> List[str]:
182
223
  """
@@ -189,15 +230,15 @@ class AsyncPostgresDB:
189
230
  List[str]: Jadval nomlari
190
231
  """
191
232
  sql = """
192
- SELECT table_name
193
- FROM information_schema.tables
194
- WHERE table_schema = $1
195
- ORDER BY table_name
196
- """
197
- result = await self.manager(sql, schema, fetchall=True)
233
+ SELECT table_name
234
+ FROM information_schema.tables
235
+ WHERE table_schema = $1
236
+ ORDER BY table_name \
237
+ """
238
+ result = await self._manager(sql, schema, fetchall=True)
198
239
  return [r["table_name"] for r in result]
199
240
 
200
- async def describe_table(self, table: str, schema: str = "public"):
241
+ async def describe_table(self, table: str, schema: str = "public") -> List[str]:
201
242
  """
202
243
  Jadval ustunlari haqida ma'lumot beradi.
203
244
 
@@ -209,14 +250,15 @@ class AsyncPostgresDB:
209
250
  list[asyncpg.Record]: Har bir ustun bo‘yicha ma’lumot
210
251
  """
211
252
  sql = """
212
- SELECT column_name, data_type, is_nullable, column_default
213
- FROM information_schema.columns
214
- WHERE table_schema = $1 AND table_name = $2
215
- ORDER BY ordinal_position
216
- """
217
- return await self.manager(sql, schema, table, fetchall=True)
218
-
219
- async def alter(self, table: str, action: str):
253
+ SELECT column_name, data_type, is_nullable, column_default
254
+ FROM information_schema.columns
255
+ WHERE table_schema = $1
256
+ AND table_name = $2
257
+ ORDER BY ordinal_position \
258
+ """
259
+ return await self._manager(sql, schema, table, fetchall=True)
260
+
261
+ async def alter(self, table: str, action: str) -> None:
220
262
  """
221
263
  Jadval strukturasi o‘zgartirish (ALTER TABLE).
222
264
 
@@ -225,4 +267,4 @@ class AsyncPostgresDB:
225
267
  action (str): ALTER TABLE dan keyingi SQL qismi, misol: "ADD COLUMN age INT".
226
268
  """
227
269
  sql = f"ALTER TABLE {table} {action}"
228
- await self.manager(sql, commit=True)
270
+ await self._manager(sql, commit=True)
@@ -0,0 +1,344 @@
1
+ from typing import Any
2
+ import psycopg2
3
+
4
+
5
+ class PostgresDB:
6
+
7
+ def __init__(self, database: str, user: str, password: str, host: str = "localhost", port: int = 5432) -> None:
8
+ """
9
+ PostgreSQL bazasiga ulanish.
10
+
11
+ Parametrlar:
12
+ database (str): Bazaning nomi
13
+ user (str): Foydalanuvchi
14
+ password (str): Parol
15
+ host (str): Server manzili (standart = localhost)
16
+ port (int): Port (standart = 5432)
17
+ """
18
+ self.connection = psycopg2.connect(
19
+ database=database, user=user, password=password, host=host, port=port
20
+ )
21
+
22
+ def _manager(
23
+ self,
24
+ sql: str,
25
+ params: list | tuple | None = None,
26
+ *,
27
+ commit: bool = False,
28
+ many: bool = False,
29
+ fetchone: bool = False,
30
+ fetchall: bool = False,
31
+ fetchmany: int | None = None
32
+ ) -> Any:
33
+ """
34
+ SQL so'rovlarini xavfsiz bajaruvchi yagona, ichki metod.
35
+
36
+ Bu metod **protected** bo‘lib, tashqaridan ishlatish tavsiya etilmaydi.
37
+ Public uchun `raw()` metodini ishlatish yaxshiroq.
38
+
39
+ Parametrlar
40
+ ----------
41
+ sql : str
42
+ Bajariladigan SQL so'rov. Majburiy.
43
+ params : tuple, list yoki None, ixtiyoriy
44
+ SQL so‘rovga parametrlarni bog‘lash uchun ishlatiladi. Default: None.
45
+ Agar `many=True` bo‘lsa, bu **tuple lar ro‘yxati** bo‘lishi kerak.
46
+ commit : bool, ixtiyoriy
47
+ Agar True bo‘lsa, tranzaksiya bajarilgandan keyin commit qilinadi.
48
+ Default: False. INSERT, UPDATE, DELETE kabi so‘rovlar uchun kerak.
49
+ many : bool, ixtiyoriy
50
+ Agar True bo‘lsa, so‘rovni bir nechta parametrlar bilan qayta bajaradi
51
+ (`cursor.executemany()` ishlatiladi). Default: False.
52
+ `fetchone`, `fetchall` yoki `fetchmany` bilan birga ishlatilmaydi.
53
+ fetchone : bool, ixtiyoriy
54
+ Agar True bo‘lsa, so‘rov natijasidan faqat bitta qator qaytariladi.
55
+ Default: False. `fetchall`, `fetchmany` yoki `many=True` bilan ishlamaydi.
56
+ fetchall : bool, ixtiyoriy
57
+ Agar True bo‘lsa, so‘rov natijasidagi barcha qatorlar qaytariladi.
58
+ Default: False. `fetchone`, `fetchmany` yoki `many=True` bilan ishlamaydi.
59
+ fetchmany : int yoki None, ixtiyoriy
60
+ Agar butun son N berilsa, so‘rov natijasidan N ta qator qaytariladi.
61
+ Default: None. `fetchone`, `fetchall` yoki `many=True` bilan ishlamaydi.
62
+
63
+ Returns
64
+ -------
65
+ result : any
66
+ So‘rov natijasi fetch parametriga bog‘liq:
67
+ - `fetchone=True` → bitta qator (tuple)
68
+ - `fetchall=True` → barcha qatorlar ro‘yxati
69
+ - `fetchmany=N` → N ta qator ro‘yxati
70
+ - `many=True` → None
71
+ - Fetch parametri ishlatilmasa → None
72
+
73
+ Raises
74
+ ------
75
+ ValueError
76
+ - Agar `sql` bo‘sh yoki None bo‘lsa.
77
+ - Agar bir vaqtda `fetchone` va `fetchall` True bo‘lsa.
78
+ - Agar `many=True` fetch parametrlar bilan birga ishlatilsa.
79
+
80
+ Izohlar
81
+ --------
82
+ - Bu metod connection va cursor ni context manager orqali avtomatik boshqaradi.
83
+ - Exceptionlar va tranzaksiya nazorati psycopg2 tomonidan amalga oshiriladi.
84
+ - Tashqarida ishlatishda `raw()` yoki yuqori darajadagi metodlar (`insert()`, `select()`, `insert_many()`) ishlatilishi tavsiya etiladi.
85
+ - Tashqaridan bevosita chaqirish tavsiya etilmaydi.
86
+ """
87
+
88
+ if fetchone and fetchall:
89
+ raise ValueError("fetchone and fetchall cannot be True at the same time")
90
+ if many and (fetchone or fetchall or fetchmany):
91
+ raise ValueError("cannot use fetchone/fetchall/fetchmany with many=True")
92
+
93
+ with self.connection.cursor() as cursor:
94
+ if many:
95
+ cursor.executemany(sql, params)
96
+ result = None
97
+ else:
98
+ cursor.execute(sql, params)
99
+ if fetchone:
100
+ result = cursor.fetchone()
101
+ elif fetchall:
102
+ result = cursor.fetchall()
103
+ elif fetchmany is not None:
104
+ result = cursor.fetchmany(fetchmany)
105
+ else:
106
+ result = None
107
+
108
+ if commit:
109
+ self.connection.commit()
110
+
111
+ return result
112
+
113
+ def close(self) -> None:
114
+ self.connection.close()
115
+
116
+ def raw(
117
+ self,
118
+ sql: str,
119
+ params: list | tuple | None = None,
120
+ *,
121
+ commit: bool = False,
122
+ many: bool = False,
123
+ fetchone: bool = False,
124
+ fetchall: bool = False,
125
+ fetchmany: int | None = None
126
+ ) -> Any:
127
+ """
128
+ SQL so'rovini bevosita bajarish (raw execution).
129
+
130
+ Faqat ilg'or foydalanish uchun. Bu metod ichki `_manager` metodini chaqiradi.
131
+ Tashqaridan oddiy foydalanuvchilar uchun `select()`, `insert()`, `update()`,
132
+ `delete()` yoki `insert_many()` metodlarini ishlatish tavsiya etiladi.
133
+
134
+ Parametrlar
135
+ ----------
136
+ sql : str
137
+ Bajariladigan SQL so'rov. Majburiy.
138
+ params : tuple, list yoki None, ixtiyoriy
139
+ SQL so‘rovga parametrlarni bog‘lash uchun ishlatiladi. Default: None.
140
+ commit : bool, ixtiyoriy
141
+ Agar True bo‘lsa, tranzaksiya bajarilgandan keyin commit qilinadi.
142
+ Default: False.
143
+ fetchone : bool, ixtiyoriy
144
+ Agar True bo‘lsa, so‘rov natijasidan faqat bitta qator qaytariladi.
145
+ Default: False. `fetchall` bilan birga ishlatilmaydi.
146
+ fetchall : bool, ixtiyoriy
147
+ Agar True bo‘lsa, so‘rov natijasidagi barcha qatorlar qaytariladi.
148
+ Default: False. `fetchone` bilan birga ishlatilmaydi.
149
+
150
+ Returns
151
+ -------
152
+ result : any
153
+ So‘rov natijasi fetch parametriga bog‘liq:
154
+ - `fetchone=True` → bitta qator (tuple)
155
+ - `fetchall=True` → barcha qatorlar ro‘yxati
156
+ - Hech qaysi fetch parametr ishlatilmasa → None
157
+
158
+ Raises
159
+ ------
160
+ ValueError
161
+ - Agar bir vaqtda `fetchone` va `fetchall` True bo‘lsa.
162
+
163
+ Misol
164
+ ------
165
+ >>> db.raw("SELECT * FROM users WHERE age > %s", (18,), fetchall=True)
166
+ """
167
+ if fetchone and fetchall:
168
+ raise ValueError("fetchone va fetchall bir vaqtda True bo‘la olmaydi")
169
+
170
+ return self._manager(
171
+ sql,
172
+ params,
173
+ commit=commit,
174
+ many=many,
175
+ fetchone=fetchone,
176
+ fetchall=fetchall,
177
+ fetchmany=fetchmany,
178
+ )
179
+
180
+ def create(self, table: str, columns: str) -> None:
181
+ """
182
+ table: str - jadval nomi
183
+ columns: str - ustunlar va turlari, misol: "id SERIAL PRIMARY KEY, name VARCHAR(100)"
184
+ """
185
+ sql = f"CREATE TABLE IF NOT EXISTS {table} ({columns})"
186
+ self._manager(sql, commit=True)
187
+
188
+ def drop(self, table: str) -> None:
189
+ """
190
+ table: str - o'chiriladigan jadval nomi
191
+ """
192
+ sql = f"DROP TABLE IF EXISTS {table} CASCADE"
193
+ self._manager(sql, commit=True)
194
+
195
+ def select(
196
+ self,
197
+ table: str,
198
+ columns: str = "*",
199
+ where: tuple | None = None,
200
+ join: list[tuple] | None = None,
201
+ group_by: str | None = None,
202
+ order_by: str | None = None,
203
+ limit: int | None = None,
204
+ fetchone: bool = False
205
+ ) -> Any:
206
+ """
207
+ table: str — asosiy jadval
208
+ columns: str — tanlanadigan ustunlar ("id, name")
209
+ where: tuple | None — ("age > %s", [18])
210
+ join: list | None — [("INNER JOIN", "orders", "users.id = orders.user_id")]
211
+ group_by: str | None — "age"
212
+ order_by: str | None — "age DESC"
213
+ limit: int | None
214
+ """
215
+
216
+ sql = f"SELECT {columns} FROM {table}"
217
+ params = []
218
+
219
+ if join:
220
+ for join_type, join_table, on_condition in join:
221
+ sql += f" {join_type} {join_table} ON {on_condition}"
222
+
223
+ if where:
224
+ condition, values = where
225
+ sql += f" WHERE {condition}"
226
+ params.extend(values)
227
+
228
+ if group_by:
229
+ sql += f" GROUP BY {group_by}"
230
+
231
+ if order_by:
232
+ sql += f" ORDER BY {order_by}"
233
+
234
+ if limit:
235
+ sql += f" LIMIT %s"
236
+ params.append(limit)
237
+
238
+ if fetchone:
239
+ return self._manager(sql, params, fetchone=True)
240
+ return self._manager(sql, params, fetchall=True)
241
+
242
+ def insert(self, table: str, columns: str, values: tuple | list) -> None:
243
+ """
244
+ table: str - jadval nomi
245
+ columns: str - ustunlar, misol: "name, email, age"
246
+ values: tuple yoki list - ustun qiymatlari, misol: ("Ali", "ali@mail.com", 25)
247
+ """
248
+ placeholders = ", ".join(["%s"] * len(values))
249
+ sql = f"INSERT INTO {table} ({columns}) VALUES ({placeholders})"
250
+ self._manager(sql, values, commit=True)
251
+
252
+ def insert_many(self, table: str, columns: str, values_list: list[tuple]) -> None:
253
+ """
254
+ Jadvalga bir nechta qatorni qo'shish (bulk insert).
255
+
256
+ Parametrlar
257
+ ----------
258
+ table : str
259
+ Jadval nomi.
260
+ columns : str
261
+ Ustunlar, misol: "name, email, age".
262
+ values_list : list of tuples
263
+ Har tuple bitta qator qiymatlari, misol:
264
+ [("Ali", "ali@mail.com", 25), ("Vali", "vali@mail.com", 30)]
265
+
266
+ Misol
267
+ ------
268
+ >>> db.insert_many(
269
+ ... "users",
270
+ ... "name, email, age",
271
+ ... [("Ali", "ali@mail.com", 25), ("Vali", "vali@mail.com", 30)]
272
+ ... )
273
+ """
274
+ if not values_list:
275
+ raise ValueError("values_list bo'sh bo'lishi mumkin emas")
276
+
277
+ placeholders = ", ".join(["%s"] * len(values_list[0]))
278
+ sql = f"INSERT INTO {table} ({columns}) VALUES ({placeholders})"
279
+
280
+ self._manager(sql, values_list, commit=True, many=True)
281
+
282
+ def update(self, table: str, set_column: str, set_value: Any, where_column: str, where_value: Any) -> None:
283
+ """
284
+ Jadvaldagi ma'lumotni yangilash.
285
+
286
+ Parametrlar:
287
+ table (str): Jadval nomi.
288
+ set_column (str): O'zgartiriladigan ustun.
289
+ set_value (Any): Yangi qiymat.
290
+ where_column (str): Filtrlash ustuni.
291
+ where_value (Any): Qaysi qatorda o'zgarish bo'lishi.
292
+
293
+ Izoh:
294
+ Faqat WHERE shartiga mos kelgan qatorlar yangilanadi.
295
+ """
296
+ sql = f"UPDATE {table} SET {set_column} = %s WHERE {where_column} = %s"
297
+ self._manager(sql, (set_value, where_value), commit=True)
298
+
299
+ def delete(self, table: str, where_column: str, where_value: Any) -> None:
300
+ """
301
+ Jadvaldan qator o'chirish.
302
+ """
303
+ sql = f"DELETE FROM {table} WHERE {where_column} = %s"
304
+ self._manager(sql, (where_value,), commit=True)
305
+
306
+ def list_tables(self, schema="public") -> list[tuple]:
307
+ """
308
+ Bazadagi mavjud jadvallar ro'yxatini qaytaradi.
309
+
310
+ schema: str — schema nomi (standart: public)
311
+ """
312
+ sql = """
313
+ SELECT table_name
314
+ FROM information_schema.tables
315
+ WHERE table_schema = %s
316
+ ORDER BY table_name; \
317
+ """
318
+ return self._manager(sql, (schema,), fetchall=True)
319
+
320
+ def describe_table(self, table: str, schema: str = "public") -> list[tuple]:
321
+ """
322
+ Jadval ustunlari haqida ma'lumot beradi.
323
+ """
324
+ sql = """
325
+ SELECT column_name,
326
+ data_type,
327
+ is_nullable,
328
+ column_default
329
+ FROM information_schema.columns
330
+ WHERE table_schema = %s
331
+ AND table_name = %s
332
+ ORDER BY ordinal_position; \
333
+ """
334
+ return self._manager(sql, (schema, table), fetchall=True)
335
+
336
+ def alter(self, table: str, action: str) -> Any:
337
+ """
338
+ Universal ALTER TABLE metodi.
339
+
340
+ table: str — jadval nomi
341
+ action: str — ALTER TABLE dan keyingi qism
342
+ """
343
+ sql = f"ALTER TABLE {table} {action}"
344
+ return self._manager(sql, commit=True)
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: postgresdb3
3
- Version: 0.2.2
3
+ Version: 0.3.0
4
4
  Summary: Python uchun oddiy PostgreSQL wrapper
5
- Home-page: https://github.com/AlijonovUz/PostgresDB
6
5
  Author: Abdulbosit Alijonov
6
+ Project-URL: Source Code, https://github.com/AlijonovUz/PostgresDB
7
7
  Classifier: Programming Language :: Python :: 3
8
8
  Classifier: License :: OSI Approved :: MIT License
9
9
  Classifier: Operating System :: OS Independent
@@ -15,7 +15,7 @@ Dynamic: author
15
15
  Dynamic: classifier
16
16
  Dynamic: description
17
17
  Dynamic: description-content-type
18
- Dynamic: home-page
18
+ Dynamic: project-url
19
19
  Dynamic: requires-dist
20
20
  Dynamic: requires-python
21
21
  Dynamic: summary
@@ -31,7 +31,7 @@ Oddiy va qulay Python wrapper PostgreSQL bazasi bilan ishlash uchun.
31
31
  ## O'rnatish
32
32
 
33
33
  ``` bash
34
- pip install postgresdb3
34
+ pip install postgresdb3
35
35
  ```
36
36
 
37
37
  ## Foydalanish (Sync)
@@ -5,7 +5,7 @@ with open("README.md", "r", encoding="utf-8") as f:
5
5
 
6
6
  setup(
7
7
  name="postgresdb3",
8
- version="0.2.2",
8
+ version="0.3.0",
9
9
  packages=find_packages(),
10
10
  install_requires=[
11
11
  "psycopg2>=2.9",
@@ -15,7 +15,9 @@ setup(
15
15
  description="Python uchun oddiy PostgreSQL wrapper",
16
16
  long_description=long_description,
17
17
  long_description_content_type="text/markdown",
18
- url="https://github.com/AlijonovUz/PostgresDB",
18
+ project_urls={
19
+ "Source Code": "https://github.com/AlijonovUz/PostgresDB",
20
+ },
19
21
  classifiers=[
20
22
  "Programming Language :: Python :: 3",
21
23
  "License :: OSI Approved :: MIT License",
@@ -1,189 +0,0 @@
1
- import psycopg2
2
-
3
-
4
- class PostgresDB:
5
-
6
- def __init__(self, database, user, password, host="localhost", port=5432):
7
- """
8
- PostgreSQL bazasiga ulanish.
9
-
10
- Parametrlar:
11
- database (str): Bazaning nomi
12
- user (str): Foydalanuvchi
13
- password (str): Parol
14
- host (str): Server manzili (standart = localhost)
15
- port (int): Port (standart = 5432)
16
- """
17
- self.connect = psycopg2.connect(
18
- database=database, user=user, password=password, host=host, port=port
19
- )
20
-
21
- def manager(
22
- self,
23
- sql=None,
24
- params=None,
25
- *,
26
- commit=False,
27
- fetchall=False,
28
- fetchone=False,
29
- ):
30
- """
31
- Barcha SQL amallarni boshqaruvchi yagona metod.
32
-
33
- Parametrlar:
34
- sql (str | None): Bajariladigan SQL so'rov.
35
- params (tuple | list | None): Parametrlar.
36
- commit (bool): Tranzaksiyani tasdiqlash.
37
- fetchall (bool): Barcha natijalarni olish.
38
- fetchone (bool): Bitta natija olish.
39
- """
40
-
41
- with self.connect as connect:
42
- result = None
43
- with connect.cursor() as cursor:
44
- cursor.execute(sql, params)
45
-
46
- if commit:
47
- connect.commit()
48
- elif fetchall:
49
- result = cursor.fetchall()
50
- elif fetchone:
51
- result = cursor.fetchone()
52
-
53
- return result
54
-
55
- def create(self, table, columns):
56
- """
57
- table: str - jadval nomi
58
- columns: str - ustunlar va turlari, misol: "id SERIAL PRIMARY KEY, name VARCHAR(100)"
59
- """
60
- sql = f"CREATE TABLE IF NOT EXISTS {table} ({columns})"
61
- self.manager(sql, commit=True)
62
-
63
- def drop(self, table):
64
- """
65
- table: str - o'chiriladigan jadval nomi
66
- """
67
- sql = f"DROP TABLE IF EXISTS {table} CASCADE"
68
- self.manager(sql, commit=True)
69
-
70
- def select(
71
- self,
72
- table,
73
- columns="*",
74
- where=None,
75
- join=None,
76
- group_by=None,
77
- order_by=None,
78
- limit=None,
79
- fetchone=False,
80
- ):
81
- """
82
- table: str — asosiy jadval
83
- columns: str — tanlanadigan ustunlar ("id, name")
84
- where: tuple | None — ("age > %s", [18])
85
- join: list | None — [("INNER JOIN", "orders", "users.id = orders.user_id")]
86
- group_by: str | None — "age"
87
- order_by: str | None — "age DESC"
88
- limit: int | None
89
- """
90
-
91
- sql = f"SELECT {columns} FROM {table}"
92
- params = []
93
-
94
- if join:
95
- for join_type, join_table, on_condition in join:
96
- sql += f" {join_type} {join_table} ON {on_condition}"
97
-
98
- if where:
99
- condition, values = where
100
- sql += f" WHERE {condition}"
101
- params.extend(values)
102
-
103
- if group_by:
104
- sql += f" GROUP BY {group_by}"
105
-
106
- if order_by:
107
- sql += f" ORDER BY {order_by}"
108
-
109
- if limit:
110
- sql += f" LIMIT %s"
111
- params.append(limit)
112
-
113
- if fetchone:
114
- return self.manager(sql, params, fetchone=True)
115
- return self.manager(sql, params, fetchall=True)
116
-
117
- def insert(self, table, columns, values):
118
- """
119
- table: str - jadval nomi
120
- columns: str - ustunlar, misol: "name, email, age"
121
- values: tuple yoki list - ustun qiymatlari, misol: ("Ali", "ali@mail.com", 25)
122
- """
123
- placeholders = ", ".join(["%s"] * len(values))
124
- sql = f"INSERT INTO {table} ({columns}) VALUES ({placeholders})"
125
- self.manager(sql, values, commit=True)
126
-
127
- def update(self, table, set_column, set_value, where_column, where_value):
128
- """
129
- Jadvaldagi ma'lumotni yangilash.
130
-
131
- Parametrlar:
132
- table (str): Jadval nomi.
133
- set_column (str): O'zgartiriladigan ustun.
134
- set_value (Any): Yangi qiymat.
135
- where_column (str): Filtrlash ustuni.
136
- where_value (Any): Qaysi qatorda o'zgarish bo'lishi.
137
-
138
- Izoh:
139
- Faqat WHERE shartiga mos kelgan qatorlar yangilanadi.
140
- """
141
- sql = f"UPDATE {table} SET {set_column} = %s WHERE {where_column} = %s"
142
- return self.manager(sql, (set_value, where_value), commit=True)
143
-
144
- def delete(self, table, where_column, where_value):
145
- """
146
- Jadvaldan qator o'chirish.
147
- """
148
- sql = f"DELETE FROM {table} WHERE {where_column} = %s"
149
- return self.manager(sql, (where_value,), commit=True)
150
-
151
- def list_tables(self, schema="public"):
152
- """
153
- Bazadagi mavjud jadvallar ro'yxatini qaytaradi.
154
-
155
- schema: str — schema nomi (standart: public)
156
- """
157
- sql = """
158
- SELECT table_name
159
- FROM information_schema.tables
160
- WHERE table_schema = %s
161
- ORDER BY table_name; \
162
- """
163
- return self.manager(sql, (schema,), fetchall=True)
164
-
165
- def describe_table(self, table, schema="public"):
166
- """
167
- Jadval ustunlari haqida ma'lumot beradi.
168
- """
169
- sql = """
170
- SELECT column_name,
171
- data_type,
172
- is_nullable,
173
- column_default
174
- FROM information_schema.columns
175
- WHERE table_schema = %s
176
- AND table_name = %s
177
- ORDER BY ordinal_position; \
178
- """
179
- return self.manager(sql, (schema, table), fetchall=True)
180
-
181
- def alter(self, table, action):
182
- """
183
- Universal ALTER TABLE metodi.
184
-
185
- table: str — jadval nomi
186
- action: str — ALTER TABLE dan keyingi qism
187
- """
188
- sql = f"ALTER TABLE {table} {action}"
189
- return self.manager(sql, commit=True)
File without changes
File without changes