psqlpy 0.11.2__pp311-pypy311_pp73-musllinux_1_2_i686.whl

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.

Potentially problematic release.


This version of psqlpy might be problematic. Click here for more details.

@@ -0,0 +1,1775 @@
1
+ import types
2
+ from enum import Enum
3
+ from io import BytesIO
4
+ from ipaddress import IPv4Address, IPv6Address
5
+ from typing import Any, Awaitable, Callable, Mapping, Sequence, TypeVar
6
+
7
+ from typing_extensions import Buffer, Self, TypeAlias
8
+
9
+ _CustomClass = TypeVar(
10
+ "_CustomClass",
11
+ )
12
+ _RowFactoryRV = TypeVar(
13
+ "_RowFactoryRV",
14
+ )
15
+
16
+ ParamsT: TypeAlias = Sequence[Any] | Mapping[str, Any] | None
17
+
18
+ class QueryResult:
19
+ """Result."""
20
+
21
+ def result(
22
+ self: Self,
23
+ custom_decoders: dict[str, Callable[[bytes], Any]] | None = None,
24
+ ) -> list[dict[Any, Any]]:
25
+ """Return result from database as a list of dicts.
26
+
27
+ `custom_decoders` must be used when you use
28
+ PostgreSQL Type which isn't supported, read more in our docs.
29
+ """
30
+ def as_class(
31
+ self: Self,
32
+ as_class: Callable[..., _CustomClass],
33
+ ) -> list[_CustomClass]:
34
+ """Convert results to passed class.
35
+
36
+ The main goal of this method is pydantic,
37
+ msgspec and dataclasses support.
38
+
39
+ ### Parameters:
40
+ - `as_class`: Any callable python class for the results.
41
+
42
+ ### Example:
43
+ ```python
44
+ import asyncio
45
+
46
+ from psqlpy import PSQLPool, QueryResult
47
+
48
+ class ExampleOfAsClass:
49
+ def __init__(self, username: str) -> None:
50
+ self.username = username
51
+
52
+ async def main() -> None:
53
+ db_pool = PSQLPool()
54
+ query_result: QueryResult = await db_pool.execute(
55
+ "SELECT username FROM users WHERE id = $1",
56
+ [100],
57
+ )
58
+ class_results: List[ExampleOfAsClass] = query_result.as_class(
59
+ as_class=ExampleOfAsClass,
60
+ )
61
+ ```
62
+ """
63
+ def row_factory(
64
+ self,
65
+ row_factory: Callable[[dict[str, Any]], _RowFactoryRV],
66
+ custom_decoders: dict[str, Callable[[bytes], Any]] | None = None,
67
+ ) -> list[_RowFactoryRV]:
68
+ """Use custom function to convert results from database.
69
+
70
+ `custom_decoders` must be used when you use
71
+ PostgreSQL Type isn't supported, read more in the docs.
72
+
73
+ Argument order: firstly we apply `custom_decoders` (if specified),
74
+ then we apply `row_factory`.
75
+
76
+ ### Parameters:
77
+ - `row_factory`: function which takes `dict[str, Any]` as an argument.
78
+ - `custom_decoders`: functions for custom decoding.
79
+
80
+ ### Returns:
81
+ List of type that return passed `row_factory`.
82
+ """
83
+
84
+ class SingleQueryResult:
85
+ """Single result."""
86
+
87
+ def result(
88
+ self: Self,
89
+ custom_decoders: dict[str, Callable[[bytes], Any]] | None = None,
90
+ ) -> dict[Any, Any]:
91
+ """Return result from database as a dict.
92
+
93
+ `custom_decoders` must be used when you use
94
+ PostgreSQL Type which isn't supported, read more in our docs.
95
+ """
96
+ def as_class(
97
+ self: Self,
98
+ as_class: Callable[..., _CustomClass],
99
+ ) -> list[_CustomClass]:
100
+ """Convert results to passed class.
101
+
102
+ The main goal of this method is pydantic,
103
+ msgspec and dataclasses support.
104
+
105
+ ### Parameters:
106
+ - `as_class`: Any callable python class for the results.
107
+
108
+ ### Example:
109
+ ```python
110
+ import asyncio
111
+
112
+ from psqlpy import PSQLPool, QueryResult
113
+
114
+ class ExampleOfAsClass:
115
+ def __init__(self, username: str) -> None:
116
+ self.username = username
117
+
118
+ async def main() -> None:
119
+ db_pool = PSQLPool()
120
+ connection = await db_pool.connection()
121
+ async with connection.transaction() as trans:
122
+ query_result: SingleQueryResult = await trans.fetch_row(
123
+ "SELECT username FROM users WHERE id = $1",
124
+ [100],
125
+ )
126
+
127
+ class_result: ExampleOfAsClass = query_result.as_class(
128
+ as_class=ExampleOfAsClass,
129
+ )
130
+ ```
131
+ """
132
+ def row_factory(
133
+ self,
134
+ row_factory: Callable[[dict[str, Any]], _RowFactoryRV],
135
+ custom_decoders: dict[str, Callable[[bytes], Any]] | None = None,
136
+ ) -> _RowFactoryRV:
137
+ """Use custom function to convert results from database.
138
+
139
+ `custom_decoders` must be used when you use
140
+ PostgreSQL Type isn't supported, read more in our docs.
141
+
142
+ Argument order: firstly we apply `custom_decoders` (if specified),
143
+ then we apply `row_factory`.
144
+
145
+ ### Parameters:
146
+ - `row_factory`: function which takes `list[dict[str, Any]]` as an argument.
147
+ - `custom_decoders`: functions for custom decoding.
148
+
149
+ ### Returns:
150
+ Type that return passed function.
151
+ """
152
+
153
+ class IsolationLevel(Enum):
154
+ """Isolation Level for transactions."""
155
+
156
+ ReadUncommitted = 1
157
+ ReadCommitted = 2
158
+ RepeatableRead = 3
159
+ Serializable = 4
160
+
161
+ class LoadBalanceHosts(Enum):
162
+ """Load balancing configuration."""
163
+
164
+ # Make connection attempts to hosts in the order provided.
165
+ Disable = 1
166
+ # Make connection attempts to hosts in a random order.
167
+ Random = 2
168
+
169
+ class TargetSessionAttrs(Enum):
170
+ """Properties required of a session."""
171
+
172
+ # No special properties are required.
173
+ Any = 1
174
+ # The session must allow writes.
175
+ ReadWrite = 2
176
+ # The session allow only reads.
177
+ ReadOnly = 3
178
+
179
+ class ReadVariant(Enum):
180
+ """Class for Read Variant for transaction."""
181
+
182
+ ReadOnly = 1
183
+ ReadWrite = 2
184
+
185
+ class ConnRecyclingMethod(Enum):
186
+ """Possible methods of how a connection is recycled.
187
+
188
+ The default is [`Fast`] which does not check the connection health or
189
+ perform any clean-up queries.
190
+
191
+ # Description:
192
+ ## Fast:
193
+ Only run [`is_closed()`] when recycling existing connections.
194
+
195
+ Unless you have special needs this is a safe choice.
196
+
197
+ ## Verified:
198
+ Run [`is_closed()`] and execute a test query.
199
+
200
+ This is slower, but guarantees that the database connection is ready to
201
+ be used. Normally, [`is_closed()`] should be enough to filter
202
+ out bad connections, but under some circumstances (i.e. hard-closed
203
+ network connections) it's possible that [`is_closed()`]
204
+ returns `false` while the connection is dead. You will receive an error
205
+ on your first query then.
206
+
207
+ ## Clean:
208
+ Like [`Verified`] query method, but instead use the following sequence
209
+ of statements which guarantees a pristine connection:
210
+ ```sql
211
+ CLOSE ALL;
212
+ SET SESSION AUTHORIZATION DEFAULT;
213
+ RESET ALL;
214
+ UNLISTEN *;
215
+ SELECT pg_advisory_unlock_all();
216
+ DISCARD TEMP;
217
+ DISCARD SEQUENCES;
218
+ ```
219
+ This is similar to calling `DISCARD ALL`. but doesn't call
220
+ `DEALLOCATE ALL` and `DISCARD PLAN`, so that the statement cache is not
221
+ rendered ineffective.
222
+ """
223
+
224
+ Fast = 1
225
+ Verified = 2
226
+ Clean = 3
227
+
228
+ class SslMode(Enum):
229
+ """TLS configuration."""
230
+
231
+ # Do not use TLS.
232
+ Disable = 1
233
+ # Pay the overhead of encryption if the server insists on it.
234
+ Allow = 2
235
+ # Attempt to connect with TLS but allow sessions without.
236
+ Prefer = 3
237
+ # Require the use of TLS.
238
+ Require = 4
239
+ # I want my data encrypted,
240
+ # and I accept the overhead.
241
+ # I want to be sure that I connect to a server that I trust.
242
+ VerifyCa = 5
243
+ # I want my data encrypted,
244
+ # and I accept the overhead.
245
+ # I want to be sure that I connect to a server I trust,
246
+ # and that it's the one I specify.
247
+ VerifyFull = 6
248
+
249
+ class KeepaliveConfig:
250
+ """Config for configuring keepalive."""
251
+
252
+ def __init__(self: Self, idle: int, interval: int, retries: int) -> None:
253
+ """Initialize new config."""
254
+
255
+ class Cursor:
256
+ """Represent binary cursor in a transaction.
257
+
258
+ It can be used as an asynchronous iterator.
259
+ """
260
+
261
+ array_size: int
262
+ cursor_name: str
263
+ querystring: str
264
+ parameters: ParamsT = None
265
+ prepared: bool | None
266
+ conn_dbname: str | None
267
+ user: str | None
268
+ host_addrs: list[str]
269
+ hosts: list[str]
270
+ ports: list[int]
271
+
272
+ def __aiter__(self: Self) -> Self: ...
273
+ async def __anext__(self: Self) -> QueryResult: ...
274
+ async def __aenter__(self: Self) -> Self: ...
275
+ async def __aexit__(
276
+ self: Self,
277
+ exception_type: type[BaseException] | None,
278
+ exception: BaseException | None,
279
+ traceback: types.TracebackType | None,
280
+ ) -> None: ...
281
+ async def start(self: Self) -> None:
282
+ """Start the cursor.
283
+
284
+ Execute DECLARE command for the cursor.
285
+ """
286
+ def close(self: Self) -> None:
287
+ """Close the cursor.
288
+
289
+ Execute CLOSE command for the cursor.
290
+ """
291
+ async def execute(
292
+ self: Self,
293
+ querystring: str,
294
+ parameters: ParamsT = None,
295
+ ) -> QueryResult:
296
+ """Start cursor with querystring and parameters.
297
+
298
+ Method should be used instead of context manager
299
+ and `start` method.
300
+ """
301
+ async def fetchone(self: Self) -> QueryResult:
302
+ """Return next one row from the cursor."""
303
+ async def fetchmany(self: Self, size: int | None = None) -> QueryResult:
304
+ """Return <size> rows from the cursor."""
305
+ async def fetchall(self: Self, size: int | None = None) -> QueryResult:
306
+ """Return all remaining rows from the cursor."""
307
+
308
+ class Transaction:
309
+ """Single connection for executing queries.
310
+
311
+ It represents transaction in database.
312
+
313
+ You can create it only from `PSQLPool` with method
314
+ `.transaction()`.
315
+ """
316
+
317
+ conn_dbname: str | None
318
+ user: str | None
319
+ host_addrs: list[str]
320
+ hosts: list[str]
321
+ ports: list[int]
322
+
323
+ async def __aenter__(self: Self) -> Self: ...
324
+ async def __aexit__(
325
+ self: Self,
326
+ exception_type: type[BaseException] | None,
327
+ exception: BaseException | None,
328
+ traceback: types.TracebackType | None,
329
+ ) -> None: ...
330
+ async def begin(self: Self) -> None:
331
+ """Start the transaction.
332
+
333
+ Execute `BEGIN`.
334
+
335
+ `begin()` can be called only once per transaction.
336
+ """
337
+ async def commit(self: Self) -> None:
338
+ """Commit the transaction.
339
+
340
+ Execute `COMMIT`.
341
+
342
+ `commit()` can be called only once per transaction.
343
+ """
344
+ async def rollback(self: Self) -> None:
345
+ """Rollback all queries in the transaction.
346
+
347
+ It can be done only one, after execution transaction marked
348
+ as `done`.
349
+
350
+ ### Example:
351
+ ```python
352
+ import asyncio
353
+
354
+ from psqlpy import PSQLPool, QueryResult
355
+
356
+ async def main() -> None:
357
+ db_pool = PSQLPool()
358
+ connection = await db_pool.connection()
359
+ transaction = connection.transaction()
360
+ await transaction.execute(...)
361
+ await transaction.rollback()
362
+ ```
363
+ """
364
+ async def execute(
365
+ self: Self,
366
+ querystring: str,
367
+ parameters: ParamsT = None,
368
+ prepared: bool = True,
369
+ ) -> QueryResult:
370
+ """Execute the query.
371
+
372
+ Querystring can contain `$<number>` parameters
373
+ for converting them in the driver side.
374
+
375
+ ### Parameters:
376
+ - `querystring`: querystring to execute.
377
+ - `parameters`: list of parameters to pass in the query.
378
+ - `prepared`: should the querystring be prepared before the request.
379
+ By default any querystring will be prepared.
380
+
381
+ ### Example:
382
+ ```python
383
+ import asyncio
384
+
385
+ from psqlpy import PSQLPool, QueryResult
386
+
387
+ async def main() -> None:
388
+ db_pool = PSQLPool()
389
+ connection = await db_pool.connection()
390
+ transaction = connection.transaction()
391
+ await transaction.begin()
392
+ query_result: QueryResult = await transaction.execute(
393
+ "SELECT username FROM users WHERE id = $1",
394
+ [100],
395
+ )
396
+ dict_result: List[Dict[Any, Any]] = query_result.result()
397
+ # You must call commit manually
398
+ await transaction.commit()
399
+ ```
400
+ """
401
+ async def execute_batch(
402
+ self: Self,
403
+ querystring: str,
404
+ ) -> None:
405
+ """
406
+ Execute a sequence of SQL statements using the simple query protocol.
407
+
408
+ Statements should be separated by semicolons.
409
+ If an error occurs, execution of the sequence will stop at that point.
410
+ This is intended for use when, for example,
411
+ initializing a database schema.
412
+
413
+ ### Parameters:
414
+ - `querystring`: querystrings separated by semicolons.
415
+ """
416
+ async def execute_many(
417
+ self: Self,
418
+ querystring: str,
419
+ parameters: Sequence[Sequence[Any]] | None = None,
420
+ prepared: bool = True,
421
+ ) -> None: ...
422
+ """Execute query multiple times with different parameters.
423
+
424
+ Querystring can contain `$<number>` parameters
425
+ for converting them in the driver side.
426
+
427
+ ### Parameters:
428
+ - `querystring`: querystring to execute.
429
+ - `parameters`: list of list of parameters to pass in the query.
430
+ - `prepared`: should the querystring be prepared before the request.
431
+ By default any querystring will be prepared.
432
+
433
+ ### Example:
434
+ ```python
435
+ import asyncio
436
+
437
+ from psqlpy import PSQLPool, QueryResult
438
+
439
+
440
+ async def main() -> None:
441
+ db_pool = PSQLPool()
442
+ connection = await db_pool.connection()
443
+ transaction = connection.transaction()
444
+ await transaction.begin()
445
+ query_result: QueryResult = await transaction.execute_many(
446
+ "INSERT INTO users (name, age) VALUES ($1, $2)",
447
+ [["boba", 10], ["boba", 20]],
448
+ )
449
+ dict_result: List[Dict[Any, Any]] = query_result.result()
450
+ # You must call commit manually
451
+ await transaction.commit()
452
+ ```
453
+ """
454
+ async def fetch(
455
+ self: Self,
456
+ querystring: str,
457
+ parameters: ParamsT = None,
458
+ prepared: bool = True,
459
+ ) -> QueryResult:
460
+ """Fetch the result from database.
461
+
462
+ It's the same as `execute` method, we made it because people are used
463
+ to `fetch` method name.
464
+
465
+ Querystring can contain `$<number>` parameters
466
+ for converting them in the driver side.
467
+
468
+ ### Parameters:
469
+ - `querystring`: querystring to execute.
470
+ - `parameters`: list of parameters to pass in the query.
471
+ - `prepared`: should the querystring be prepared before the request.
472
+ By default any querystring will be prepared.
473
+ """
474
+ async def fetch_row(
475
+ self: Self,
476
+ querystring: str,
477
+ parameters: ParamsT = None,
478
+ prepared: bool = True,
479
+ ) -> SingleQueryResult:
480
+ """Fetch exaclty single row from query.
481
+
482
+ Query must return exactly one row, otherwise error will be raised.
483
+ Querystring can contain `$<number>` parameters
484
+ for converting them in the driver side.
485
+
486
+
487
+ ### Parameters:
488
+ - `querystring`: querystring to execute.
489
+ - `parameters`: list of parameters to pass in the query.
490
+ - `prepared`: should the querystring be prepared before the request.
491
+ By default any querystring will be prepared.
492
+
493
+ ### Example:
494
+ ```python
495
+ import asyncio
496
+
497
+ from psqlpy import PSQLPool, QueryResult
498
+
499
+ async def main() -> None:
500
+ db_pool = PSQLPool()
501
+ connection = await db_pool.connection()
502
+ transaction = connection.transaction()
503
+ await transaction.begin()
504
+ query_result: SingleQueryResult = await transaction.fetch_row(
505
+ "SELECT username FROM users WHERE id = $1",
506
+ [100],
507
+ )
508
+ dict_result: Dict[Any, Any] = query_result.result()
509
+ # You must call commit manually
510
+ await transaction.commit()
511
+ ```
512
+ """
513
+ async def fetch_val(
514
+ self: Self,
515
+ querystring: str,
516
+ parameters: ParamsT = None,
517
+ prepared: bool = True,
518
+ ) -> Any | None:
519
+ """Execute the query and return first value of the first row.
520
+
521
+ Returns an error if the query does not return exactly one row.
522
+
523
+ Querystring can contain `$<number>` parameters
524
+ for converting them in the driver side.
525
+
526
+ ### Parameters:
527
+ - `querystring`: querystring to execute.
528
+ - `parameters`: list of parameters to pass in the query.
529
+ - `prepared`: should the querystring be prepared before the request.
530
+ By default any querystring will be prepared.
531
+
532
+ ### Raises
533
+ - `RustPSQLDriverPyBaseError`: if the query does not
534
+ return exactly one row
535
+
536
+ ### Example:
537
+ ```python
538
+ import asyncio
539
+
540
+ from psqlpy import PSQLPool, QueryResult
541
+
542
+ async def main() -> None:
543
+ db_pool = PSQLPool()
544
+ connection = await db_pool.connection()
545
+ transaction = connection.transaction()
546
+ await transaction.begin()
547
+ value: Any = await transaction.fetch_val(
548
+ "SELECT username FROM users WHERE id = $1",
549
+ [100],
550
+ )
551
+ ```
552
+ """
553
+ async def pipeline(
554
+ self,
555
+ queries: list[tuple[str, list[Any] | None]],
556
+ prepared: bool = True,
557
+ ) -> list[QueryResult]:
558
+ """Execute queries in pipeline.
559
+
560
+ Pipelining can improve performance in use cases in which multiple,
561
+ independent queries need to be executed.
562
+ In a traditional workflow,
563
+ each query is sent to the server after the previous query completes.
564
+ In contrast, pipelining allows the client to send all of the
565
+ queries to the server up front, minimizing time spent
566
+ by one side waiting for the other to finish sending data:
567
+ ```
568
+ Sequential Pipelined
569
+ | Client | Server | | Client | Server |
570
+ |----------------|-----------------| |----------------|-----------------|
571
+ | send query 1 | | | send query 1 | |
572
+ | | process query 1 | | send query 2 | process query 1 |
573
+ | receive rows 1 | | | send query 3 | process query 2 |
574
+ | send query 2 | | | receive rows 1 | process query 3 |
575
+ | | process query 2 | | receive rows 2 | |
576
+ | receive rows 2 | | | receive rows 3 | |
577
+ | send query 3 | |
578
+ | | process query 3 |
579
+ | receive rows 3 | |
580
+ ```
581
+ Read more: https://docs.rs/tokio-postgres/latest/tokio_postgres/#pipelining
582
+
583
+ ### Parameters:
584
+ - `queries`: queries with parameters to execute.
585
+ - `prepared`: should the querystring/querystrings be prepared before the request.
586
+ By default any querystrings will be prepared.
587
+
588
+ ### Example:
589
+ ```python
590
+ import asyncio
591
+
592
+ from psqlpy import PSQLPool, QueryResult
593
+
594
+ async def main() -> None:
595
+ db_pool = PSQLPool()
596
+ connection = await db_pool.connection()
597
+ transaction = connection.transaction()
598
+
599
+ results: list[QueryResult] = await transaction.pipeline(
600
+ queries=[
601
+ (
602
+ "SELECT username FROM users WHERE id = $1",
603
+ [100],
604
+ ),
605
+ (
606
+ "SELECT some_data FROM profiles",
607
+ None,
608
+ ),
609
+ (
610
+ "INSERT INTO users (username, id) VALUES ($1, $2)",
611
+ ["PSQLPy", 1],
612
+ ),
613
+ ]
614
+ )
615
+ ```
616
+ """
617
+ async def create_savepoint(self: Self, savepoint_name: str) -> None:
618
+ """Create new savepoint.
619
+
620
+ One `savepoint_name` can be used once.
621
+
622
+
623
+ If you specify the same savepoint name more than once
624
+ exception will be raised.
625
+
626
+ ### Parameters:
627
+ - `savepoint_name`: name of the savepoint.
628
+
629
+ ### Example:
630
+ ```python
631
+ import asyncio
632
+
633
+ from psqlpy import PSQLPool, QueryResult
634
+
635
+ async def main() -> None:
636
+ db_pool = PSQLPool()
637
+ connection = await db_pool.connection()
638
+ transaction = connection.transaction()
639
+
640
+ await transaction.create_savepoint("my_savepoint")
641
+ await transaction.execute(...)
642
+ await transaction.rollback_savepoint("my_savepoint")
643
+ ```
644
+ """
645
+ async def rollback_savepoint(self: Self, savepoint_name: str) -> None:
646
+ """ROLLBACK to the specified `savepoint_name`.
647
+
648
+ If you specified wrong savepoint name
649
+ then exception will be raised.
650
+
651
+ ### Parameters:
652
+ - `savepoint_name`: name of the SAVEPOINT.
653
+
654
+ ### Example:
655
+ ```python
656
+ import asyncio
657
+
658
+ from psqlpy import PSQLPool, QueryResult
659
+
660
+ async def main() -> None:
661
+ db_pool = PSQLPool()
662
+ connection = await db_pool.connection()
663
+ transaction = connection.transaction()
664
+
665
+ await transaction.savepoint("my_savepoint")
666
+ await transaction.execute(...)
667
+ await transaction.rollback_savepoint("my_savepoint")
668
+ ```
669
+ """
670
+ async def release_savepoint(self: Self, savepoint_name: str) -> None:
671
+ """Execute ROLLBACK TO SAVEPOINT.
672
+
673
+ If you specified wrong savepoint name
674
+ then exception will be raised.
675
+
676
+ ### Parameters:
677
+ - `savepoint_name`: name of the SAVEPOINT.
678
+
679
+ ### Example:
680
+ ```python
681
+ import asyncio
682
+
683
+ from psqlpy import PSQLPool, QueryResult
684
+
685
+ async def main() -> None:
686
+ db_pool = PSQLPool()
687
+ connection = await db_pool.connection()
688
+ transaction = connection.transaction()
689
+
690
+ await transaction.savepoint("my_savepoint")
691
+ await transaction.release_savepoint
692
+ ```
693
+ """
694
+ def cursor(
695
+ self: Self,
696
+ querystring: str,
697
+ parameters: ParamsT = None,
698
+ fetch_number: int | None = None,
699
+ ) -> Cursor:
700
+ """Create new cursor object.
701
+
702
+ Cursor can be used as an asynchronous iterator.
703
+
704
+ ### Parameters:
705
+ - `querystring`: querystring to execute.
706
+ - `parameters`: list of parameters to pass in the query.
707
+ - `fetch_number`: how many rows need to fetch.
708
+
709
+ ### Returns:
710
+ new initialized cursor.
711
+
712
+ ### Example:
713
+ ```python
714
+ import asyncio
715
+
716
+ from psqlpy import PSQLPool, QueryResult
717
+
718
+ async def main() -> None:
719
+ db_pool = PSQLPool()
720
+ connection = await db_pool.connection()
721
+ transaction = await connection.transaction()
722
+
723
+ cursor = transaction.cursor(
724
+ querystring="SELECT * FROM users WHERE username = $1",
725
+ parameters=["Some_Username"],
726
+ fetch_number=5,
727
+ )
728
+ await cursor.start()
729
+
730
+ async for fetched_result in cursor:
731
+ dict_result: List[Dict[Any, Any]] = fetched_result.result()
732
+ ... # do something with this result.
733
+
734
+ await cursor.close()
735
+ ```
736
+ """
737
+ async def binary_copy_to_table(
738
+ self: Self,
739
+ source: bytes | bytearray | Buffer | BytesIO,
740
+ table_name: str,
741
+ columns: Sequence[str] | None = None,
742
+ schema_name: str | None = None,
743
+ ) -> int:
744
+ """Perform binary copy to PostgreSQL.
745
+
746
+ Execute `COPY table_name (<columns>) FROM STDIN (FORMAT binary)`
747
+ and start sending bytes to PostgreSQL.
748
+
749
+ IMPORTANT! User is responsible for the bytes passed to the database.
750
+ If bytes are incorrect user will get error from the database.
751
+
752
+ ### Parameters:
753
+ - `source`: source of bytes.
754
+ - `table_name`: name of the table.
755
+ - `columns`: sequence of str columns.
756
+ - `schema_name`: name of the schema.
757
+
758
+ ### Returns:
759
+ number of inserted rows;
760
+ """
761
+
762
+ async def connect(
763
+ dsn: str | None = None,
764
+ username: str | None = None,
765
+ password: str | None = None,
766
+ host: str | None = None,
767
+ hosts: list[str] | None = None,
768
+ port: int | None = None,
769
+ ports: list[int] | None = None,
770
+ db_name: str | None = None,
771
+ target_session_attrs: TargetSessionAttrs | None = None,
772
+ options: str | None = None,
773
+ application_name: str | None = None,
774
+ connect_timeout_sec: int | None = None,
775
+ connect_timeout_nanosec: int | None = None,
776
+ tcp_user_timeout_sec: int | None = None,
777
+ tcp_user_timeout_nanosec: int | None = None,
778
+ keepalives: bool | None = None,
779
+ keepalives_idle_sec: int | None = None,
780
+ keepalives_idle_nanosec: int | None = None,
781
+ keepalives_interval_sec: int | None = None,
782
+ keepalives_interval_nanosec: int | None = None,
783
+ keepalives_retries: int | None = None,
784
+ load_balance_hosts: LoadBalanceHosts | None = None,
785
+ ssl_mode: SslMode | None = None,
786
+ ca_file: str | None = None,
787
+ ) -> Connection:
788
+ """Create new standalone connection."""
789
+
790
+ class Connection:
791
+ """Connection from Database Connection Pool.
792
+
793
+ It can be created only from connection pool.
794
+ """
795
+
796
+ conn_dbname: str | None
797
+ user: str | None
798
+ host_addrs: list[str]
799
+ hosts: list[str]
800
+ ports: list[int]
801
+
802
+ async def __aenter__(self: Self) -> Self: ...
803
+ async def __aexit__(
804
+ self: Self,
805
+ exception_type: type[BaseException] | None,
806
+ exception: BaseException | None,
807
+ traceback: types.TracebackType | None,
808
+ ) -> None: ...
809
+ async def prepare(
810
+ self,
811
+ querystring: str,
812
+ parameters: ParamsT = None,
813
+ ) -> PreparedStatement:
814
+ """Prepare statement.
815
+
816
+ Return representation of prepared statement.
817
+ """
818
+ async def execute(
819
+ self: Self,
820
+ querystring: str,
821
+ parameters: ParamsT = None,
822
+ prepared: bool = True,
823
+ ) -> QueryResult:
824
+ """Execute the query.
825
+
826
+ Querystring can contain `$<number>` parameters
827
+ for converting them in the driver side.
828
+
829
+ ### Parameters:
830
+ - `querystring`: querystring to execute.
831
+ - `parameters`: list of parameters to pass in the query.
832
+ - `prepared`: should the querystring be prepared before the request.
833
+ By default any querystring will be prepared.
834
+
835
+ ### Returns:
836
+ query result as `QueryResult`
837
+
838
+ ### Example:
839
+ ```python
840
+ import asyncio
841
+
842
+ from psqlpy import PSQLPool, QueryResult
843
+
844
+ async def main() -> None:
845
+ db_pool = PSQLPool()
846
+ connection = await db_pool.connection()
847
+ query_result: QueryResult = await connection.execute(
848
+ "SELECT username FROM users WHERE id = $1",
849
+ [100],
850
+ )
851
+ dict_result: List[Dict[Any, Any]] = query_result.result()
852
+ ```
853
+ """
854
+ async def execute_batch(
855
+ self: Self,
856
+ querystring: str,
857
+ ) -> None:
858
+ """
859
+ Execute a sequence of SQL statements using the simple query protocol.
860
+
861
+ Statements should be separated by semicolons.
862
+ If an error occurs, execution of the sequence will stop at that point.
863
+ This is intended for use when, for example,
864
+ initializing a database schema.
865
+
866
+ ### Parameters:
867
+ - `querystring`: querystrings separated by semicolons.
868
+ """
869
+ async def execute_many(
870
+ self: Self,
871
+ querystring: str,
872
+ parameters: list[list[Any]] | None = None,
873
+ prepared: bool = True,
874
+ ) -> None: ...
875
+ """Execute query multiple times with different parameters.
876
+
877
+ Querystring can contain `$<number>` parameters
878
+ for converting them in the driver side.
879
+
880
+ ### Parameters:
881
+ - `querystring`: querystring to execute.
882
+ - `parameters`: list of list of parameters to pass in the query.
883
+ - `prepared`: should the querystring be prepared before the request.
884
+ By default any querystring will be prepared.
885
+
886
+ ### Example:
887
+ ```python
888
+ import asyncio
889
+
890
+ from psqlpy import PSQLPool, QueryResult
891
+
892
+
893
+ async def main() -> None:
894
+ db_pool = PSQLPool()
895
+ connection = await db_pool.connection()
896
+ await connection.execute_many(
897
+ "INSERT INTO users (name, age) VALUES ($1, $2)",
898
+ [["boba", 10], ["boba", 20]],
899
+ )
900
+ ```
901
+ """
902
+ async def fetch(
903
+ self: Self,
904
+ querystring: str,
905
+ parameters: ParamsT = None,
906
+ prepared: bool = True,
907
+ ) -> QueryResult:
908
+ """Fetch the result from database.
909
+
910
+ It's the same as `execute` method, we made it because people are used
911
+ to `fetch` method name.
912
+
913
+ Querystring can contain `$<number>` parameters
914
+ for converting them in the driver side.
915
+
916
+ ### Parameters:
917
+ - `querystring`: querystring to execute.
918
+ - `parameters`: list of parameters to pass in the query.
919
+ - `prepared`: should the querystring be prepared before the request.
920
+ By default any querystring will be prepared.
921
+ """
922
+ async def fetch_row(
923
+ self: Self,
924
+ querystring: str,
925
+ parameters: ParamsT = None,
926
+ prepared: bool = True,
927
+ ) -> SingleQueryResult:
928
+ """Fetch exaclty single row from query.
929
+
930
+ Query must return exactly one row, otherwise error will be raised.
931
+ Querystring can contain `$<number>` parameters
932
+ for converting them in the driver side.
933
+
934
+
935
+ ### Parameters:
936
+ - `querystring`: querystring to execute.
937
+ - `parameters`: list of parameters to pass in the query.
938
+ - `prepared`: should the querystring be prepared before the request.
939
+ By default any querystring will be prepared.
940
+
941
+ ### Example:
942
+ ```python
943
+ import asyncio
944
+
945
+ from psqlpy import PSQLPool, QueryResult
946
+
947
+ async def main() -> None:
948
+ db_pool = PSQLPool()
949
+
950
+ connection = await db_pool.connection()
951
+ query_result: SingleQueryResult = await transaction.fetch_row(
952
+ "SELECT username FROM users WHERE id = $1",
953
+ [100],
954
+ )
955
+ dict_result: Dict[Any, Any] = query_result.result()
956
+ ```
957
+ """
958
+ async def fetch_val(
959
+ self: Self,
960
+ querystring: str,
961
+ parameters: ParamsT = None,
962
+ prepared: bool = True,
963
+ ) -> Any:
964
+ """Execute the query and return first value of the first row.
965
+
966
+ Returns an error if the query does not return exactly one row.
967
+
968
+ Querystring can contain `$<number>` parameters
969
+ for converting them in the driver side.
970
+
971
+ ### Parameters:
972
+ - `querystring`: querystring to execute.
973
+ - `parameters`: list of parameters to pass in the query.
974
+ - `prepared`: should the querystring be prepared before the request.
975
+ By default any querystring will be prepared.
976
+
977
+ ### Raises
978
+ - `RustPSQLDriverPyBaseError`: if the query does not
979
+ return exactly one row
980
+
981
+ ### Example:
982
+ ```python
983
+ import asyncio
984
+
985
+ from psqlpy import PSQLPool, QueryResult
986
+
987
+ async def main() -> None:
988
+ db_pool = PSQLPool()
989
+ connection = await db_pool.connection()
990
+ # this will be an int value
991
+ query_result_value = await connection.fetch_row(
992
+ "SELECT COUNT(*) FROM users WHERE id > $1",
993
+ [100],
994
+ )
995
+ ```
996
+ """
997
+ def transaction(
998
+ self,
999
+ isolation_level: IsolationLevel | None = None,
1000
+ read_variant: ReadVariant | None = None,
1001
+ deferrable: bool | None = None,
1002
+ ) -> Transaction:
1003
+ """Create new transaction.
1004
+
1005
+ ### Parameters:
1006
+ - `isolation_level`: configure isolation level of the transaction.
1007
+ - `read_variant`: configure read variant of the transaction.
1008
+ - `deferrable`: configure deferrable of the transaction.
1009
+ """
1010
+ def cursor(
1011
+ self: Self,
1012
+ querystring: str,
1013
+ parameters: ParamsT = None,
1014
+ fetch_number: int | None = None,
1015
+ ) -> Cursor:
1016
+ """Create new cursor object.
1017
+
1018
+ Cursor can be used as an asynchronous iterator.
1019
+
1020
+ ### Parameters:
1021
+ - `querystring`: querystring to execute.
1022
+ - `parameters`: list of parameters to pass in the query.
1023
+ - `fetch_number`: how many rows need to fetch.
1024
+
1025
+ ### Returns:
1026
+ new initialized cursor.
1027
+
1028
+ ### Example:
1029
+ ```python
1030
+ import asyncio
1031
+
1032
+ from psqlpy import PSQLPool, QueryResult
1033
+
1034
+ async def main() -> None:
1035
+ db_pool = PSQLPool()
1036
+ connection = await db_pool.connection()
1037
+ async with connection.transaction():
1038
+ async with connection.cursor(
1039
+ querystring="SELECT * FROM users WHERE username = $1",
1040
+ parameters=["Some_Username"],
1041
+ fetch_number=5,
1042
+ ) as cursor:
1043
+ async for fetched_result in cursor:
1044
+ dict_result: List[Dict[Any, Any]] = fetched_result.result()
1045
+ ... # do something with this result.
1046
+ ```
1047
+ """
1048
+ def close(self: Self) -> None:
1049
+ """Return connection back to the pool.
1050
+
1051
+ It necessary to commit all transactions and close all cursor
1052
+ made by this connection. Otherwise, it won't have any practical usage.
1053
+ """
1054
+
1055
+ async def binary_copy_to_table(
1056
+ self: Self,
1057
+ source: bytes | bytearray | Buffer | BytesIO,
1058
+ table_name: str,
1059
+ columns: Sequence[str] | None = None,
1060
+ schema_name: str | None = None,
1061
+ ) -> int:
1062
+ """Perform binary copy to PostgreSQL.
1063
+
1064
+ Execute `COPY table_name (<columns>) FROM STDIN (FORMAT binary)`
1065
+ and start sending bytes to PostgreSQL.
1066
+
1067
+ IMPORTANT! User is responsible for the bytes passed to the database.
1068
+ If bytes are incorrect user will get error from the database.
1069
+
1070
+ ### Parameters:
1071
+ - `source`: source of bytes.
1072
+ - `table_name`: name of the table.
1073
+ - `columns`: sequence of str columns.
1074
+ - `schema_name`: name of the schema.
1075
+
1076
+ ### Returns:
1077
+ number of inserted rows;
1078
+ """
1079
+
1080
+ class ConnectionPoolStatus:
1081
+ max_size: int
1082
+ size: int
1083
+ available: int
1084
+ waiting: int
1085
+
1086
+ class ConnectionPool:
1087
+ """Connection pool for executing queries.
1088
+
1089
+ This is the main entrypoint in the library.
1090
+ """
1091
+
1092
+ def __init__(
1093
+ self: Self,
1094
+ dsn: str | None = None,
1095
+ username: str | None = None,
1096
+ password: str | None = None,
1097
+ host: str | None = None,
1098
+ hosts: list[str] | None = None,
1099
+ port: int | None = None,
1100
+ ports: list[int] | None = None,
1101
+ db_name: str | None = None,
1102
+ target_session_attrs: TargetSessionAttrs | None = None,
1103
+ options: str | None = None,
1104
+ application_name: str | None = None,
1105
+ connect_timeout_sec: int | None = None,
1106
+ connect_timeout_nanosec: int | None = None,
1107
+ tcp_user_timeout_sec: int | None = None,
1108
+ tcp_user_timeout_nanosec: int | None = None,
1109
+ keepalives: bool | None = None,
1110
+ keepalives_idle_sec: int | None = None,
1111
+ keepalives_idle_nanosec: int | None = None,
1112
+ keepalives_interval_sec: int | None = None,
1113
+ keepalives_interval_nanosec: int | None = None,
1114
+ keepalives_retries: int | None = None,
1115
+ load_balance_hosts: LoadBalanceHosts | None = None,
1116
+ max_db_pool_size: int = 2,
1117
+ conn_recycling_method: ConnRecyclingMethod | None = None,
1118
+ ssl_mode: SslMode | None = None,
1119
+ ca_file: str | None = None,
1120
+ ) -> None:
1121
+ """Create new PostgreSQL connection pool.
1122
+
1123
+ It connects to the database and create pool.
1124
+
1125
+ You cannot set the minimum size for the connection
1126
+ pool, by it is 0.
1127
+ `ConnectionPool` doesn't create connections on startup.
1128
+ It makes new connection on demand.
1129
+
1130
+ If you specify `dsn` parameter then `username`, `password`,
1131
+ `host`, `hosts`, `port`, `ports`, `db_name` and `target_session_attrs`
1132
+ parameters will be ignored.
1133
+
1134
+ ### Parameters:
1135
+ - `dsn`: Full dsn connection string.
1136
+ `postgres://postgres:postgres@localhost:5432/postgres?target_session_attrs=read-write`
1137
+ - `username`: Username of the user in the PostgreSQL
1138
+ - `password`: Password of the user in the PostgreSQL
1139
+ - `host`: Host of the PostgreSQL
1140
+ - `hosts`: Hosts of the PostgreSQL
1141
+ - `port`: Port of the PostgreSQL
1142
+ - `ports`: Ports of the PostgreSQL
1143
+ - `db_name`: Name of the database in PostgreSQL
1144
+ - `target_session_attrs`: Specifies requirements of the session.
1145
+ - `options`: Command line options used to configure the server
1146
+ - `application_name`: Sets the application_name parameter on the server.
1147
+ - `connect_timeout_sec`: The time limit in seconds applied to each socket-level
1148
+ connection attempt.
1149
+ Note that hostnames can resolve to multiple IP addresses,
1150
+ and this limit is applied to each address. Defaults to no timeout.
1151
+ - `connect_timeout_nanosec`: nanosec for connection timeout,
1152
+ can be used only with connect_timeout_sec.
1153
+ - `tcp_user_timeout_sec`: The time limit that
1154
+ transmitted data may remain unacknowledged
1155
+ before a connection is forcibly closed.
1156
+ This is ignored for Unix domain socket connections.
1157
+ It is only supported on systems where TCP_USER_TIMEOUT
1158
+ is available and will default to the system default if omitted
1159
+ or set to 0; on other systems, it has no effect.
1160
+ - `tcp_user_timeout_nanosec`: nanosec for cp_user_timeout,
1161
+ can be used only with tcp_user_timeout_sec.
1162
+ - `keepalives`: Controls the use of TCP keepalive.
1163
+ This option is ignored when connecting with Unix sockets.
1164
+ Defaults to on.
1165
+ - `keepalives_idle_sec`: The number of seconds of inactivity after
1166
+ which a keepalive message is sent to the server.
1167
+ This option is ignored when connecting with Unix sockets.
1168
+ Defaults to 2 hours.
1169
+ - `keepalives_idle_nanosec`: Nanosec for keepalives_idle_sec.
1170
+ - `keepalives_interval_sec`: The time interval between TCP keepalive probes.
1171
+ This option is ignored when connecting with Unix sockets.
1172
+ - `keepalives_interval_nanosec`: Nanosec for keepalives_interval_sec.
1173
+ - `keepalives_retries`: The maximum number of TCP keepalive probes
1174
+ that will be sent before dropping a connection.
1175
+ This option is ignored when connecting with Unix sockets.
1176
+ - `load_balance_hosts`: Controls the order in which the client tries to connect
1177
+ to the available hosts and addresses.
1178
+ Once a connection attempt is successful no other
1179
+ hosts and addresses will be tried.
1180
+ This parameter is typically used in combination with multiple host names
1181
+ or a DNS record that returns multiple IPs.
1182
+ If set to disable, hosts and addresses will be tried in the order provided.
1183
+ If set to random, hosts will be tried in a random order, and the IP addresses
1184
+ resolved from a hostname will also be tried in a random order.
1185
+ Defaults to disable.
1186
+ - `max_db_pool_size`: maximum size of the connection pool.
1187
+ - `conn_recycling_method`: how a connection is recycled.
1188
+ - `ssl_mode`: mode for ssl.
1189
+ - `ca_file`: Loads trusted root certificates from a file.
1190
+ The file should contain a sequence of PEM-formatted CA certificates.
1191
+ """
1192
+ def __iter__(self: Self) -> Self: ...
1193
+ def __enter__(self: Self) -> Self: ...
1194
+ def __exit__(
1195
+ self: Self,
1196
+ exception_type: type[BaseException] | None,
1197
+ exception: BaseException | None,
1198
+ traceback: types.TracebackType | None,
1199
+ ) -> None: ...
1200
+ def status(self: Self) -> ConnectionPoolStatus:
1201
+ """Return information about connection pool.
1202
+
1203
+ ### Returns
1204
+ `ConnectionPoolStatus`
1205
+ """
1206
+ def resize(self: Self, new_max_size: int) -> None:
1207
+ """Resize the connection pool.
1208
+
1209
+ This change the max_size of the pool dropping
1210
+ excess objects and/or making space for new ones.
1211
+
1212
+ ### Parameters:
1213
+ - `new_max_size`: new size for the connection pool.
1214
+ """
1215
+ async def connection(self: Self) -> Connection:
1216
+ """Create new connection.
1217
+
1218
+ It acquires new connection from the database pool.
1219
+ """
1220
+ def acquire(self: Self) -> Connection:
1221
+ """Create new connection for async context manager.
1222
+
1223
+ Must be used only in async context manager.
1224
+
1225
+ ### Example:
1226
+ ```python
1227
+ import asyncio
1228
+
1229
+ from psqlpy import PSQLPool, QueryResult
1230
+
1231
+ async def main() -> None:
1232
+ db_pool = PSQLPool()
1233
+ async with db_pool.acquire() as connection:
1234
+ res = await connection.execute(...)
1235
+ ```
1236
+ """
1237
+ def listener(self: Self) -> Listener:
1238
+ """Create new listener."""
1239
+
1240
+ def close(self: Self) -> None:
1241
+ """Close the connection pool."""
1242
+
1243
+ def connect_pool(
1244
+ dsn: str | None = None,
1245
+ username: str | None = None,
1246
+ password: str | None = None,
1247
+ host: str | None = None,
1248
+ hosts: list[str] | None = None,
1249
+ port: int | None = None,
1250
+ ports: list[int] | None = None,
1251
+ db_name: str | None = None,
1252
+ target_session_attrs: TargetSessionAttrs | None = None,
1253
+ options: str | None = None,
1254
+ application_name: str | None = None,
1255
+ connect_timeout_sec: int | None = None,
1256
+ connect_timeout_nanosec: int | None = None,
1257
+ tcp_user_timeout_sec: int | None = None,
1258
+ tcp_user_timeout_nanosec: int | None = None,
1259
+ keepalives: bool | None = None,
1260
+ keepalives_idle_sec: int | None = None,
1261
+ keepalives_idle_nanosec: int | None = None,
1262
+ keepalives_interval_sec: int | None = None,
1263
+ keepalives_interval_nanosec: int | None = None,
1264
+ keepalives_retries: int | None = None,
1265
+ load_balance_hosts: LoadBalanceHosts | None = None,
1266
+ max_db_pool_size: int = 2,
1267
+ conn_recycling_method: ConnRecyclingMethod | None = None,
1268
+ ssl_mode: SslMode | None = None,
1269
+ ca_file: str | None = None,
1270
+ ) -> ConnectionPool:
1271
+ """Create new PostgreSQL connection pool.
1272
+
1273
+ It connects to the database and create pool.
1274
+
1275
+ You cannot set the minimum size for the connection
1276
+ pool, by it is 0.
1277
+ `ConnectionPool` doesn't create connections on startup.
1278
+ It makes new connection on demand.
1279
+
1280
+ If you specify `dsn` parameter then `username`, `password`,
1281
+ `host`, `hosts`, `port`, `ports`, `db_name` and `target_session_attrs`
1282
+ parameters will be ignored.
1283
+
1284
+ ### Parameters:
1285
+ - `dsn`: Full dsn connection string.
1286
+ `postgres://postgres:postgres@localhost:5432/postgres?target_session_attrs=read-write`
1287
+ - `username`: Username of the user in the PostgreSQL
1288
+ - `password`: Password of the user in the PostgreSQL
1289
+ - `host`: Host of the PostgreSQL
1290
+ - `hosts`: Hosts of the PostgreSQL
1291
+ - `port`: Port of the PostgreSQL
1292
+ - `ports`: Ports of the PostgreSQL
1293
+ - `db_name`: Name of the database in PostgreSQL
1294
+ - `target_session_attrs`: Specifies requirements of the session.
1295
+ - `options`: Command line options used to configure the server
1296
+ - `application_name`: Sets the application_name parameter on the server.
1297
+ - `connect_timeout_sec`: The time limit in seconds applied to each socket-level
1298
+ connection attempt.
1299
+ Note that hostnames can resolve to multiple IP addresses,
1300
+ and this limit is applied to each address. Defaults to no timeout.
1301
+ - `connect_timeout_nanosec`: nanosec for connection timeout,
1302
+ can be used only with connect_timeout_sec.
1303
+ - `tcp_user_timeout_sec`: The time limit that
1304
+ transmitted data may remain unacknowledged
1305
+ before a connection is forcibly closed.
1306
+ This is ignored for Unix domain socket connections.
1307
+ It is only supported on systems where TCP_USER_TIMEOUT
1308
+ is available and will default to the system default if omitted
1309
+ or set to 0; on other systems, it has no effect.
1310
+ - `tcp_user_timeout_nanosec`: nanosec for cp_user_timeout,
1311
+ can be used only with tcp_user_timeout_sec.
1312
+ - `keepalives`: Controls the use of TCP keepalive.
1313
+ This option is ignored when connecting with Unix sockets.
1314
+ Defaults to on.
1315
+ - `keepalives_idle_sec`: The number of seconds of inactivity after
1316
+ which a keepalive message is sent to the server.
1317
+ This option is ignored when connecting with Unix sockets.
1318
+ Defaults to 2 hours.
1319
+ - `keepalives_idle_nanosec`: Nanosec for keepalives_idle_sec.
1320
+ - `keepalives_interval_sec`: The time interval between TCP keepalive probes.
1321
+ This option is ignored when connecting with Unix sockets.
1322
+ - `keepalives_interval_nanosec`: Nanosec for keepalives_interval_sec.
1323
+ - `keepalives_retries`: The maximum number of TCP keepalive probes
1324
+ that will be sent before dropping a connection.
1325
+ This option is ignored when connecting with Unix sockets.
1326
+ - `load_balance_hosts`: Controls the order in which the client tries to connect
1327
+ to the available hosts and addresses.
1328
+ Once a connection attempt is successful no other
1329
+ hosts and addresses will be tried.
1330
+ This parameter is typically used in combination with multiple host names
1331
+ or a DNS record that returns multiple IPs.
1332
+ If set to disable, hosts and addresses will be tried in the order provided.
1333
+ If set to random, hosts will be tried in a random order, and the IP addresses
1334
+ resolved from a hostname will also be tried in a random order.
1335
+ Defaults to disable.
1336
+ - `max_db_pool_size`: maximum size of the connection pool.
1337
+ - `conn_recycling_method`: how a connection is recycled.
1338
+ - `ssl_mode`: mode for ssl.
1339
+ - `ca_file`: Loads trusted root certificates from a file.
1340
+ The file should contain a sequence of PEM-formatted CA certificates.
1341
+ """
1342
+
1343
+ class ConnectionPoolBuilder:
1344
+ """Builder for `ConnectionPool`."""
1345
+
1346
+ def __init__(self: Self) -> None:
1347
+ """Initialize new instance of `ConnectionPoolBuilder`."""
1348
+ def build(self: Self) -> ConnectionPool:
1349
+ """
1350
+ Build `ConnectionPool`.
1351
+
1352
+ ### Returns:
1353
+ `ConnectionPool`
1354
+ """
1355
+ def max_pool_size(self: Self, pool_size: int) -> Self:
1356
+ """
1357
+ Set maximum connection pool size.
1358
+
1359
+ ### Parameters:
1360
+ - `pool_size`: size of the pool, must be more than 1.
1361
+
1362
+ ### Returns:
1363
+ `ConnectionPoolBuilder`
1364
+ """
1365
+ def conn_recycling_method(
1366
+ self: Self,
1367
+ conn_recycling_method: ConnRecyclingMethod,
1368
+ ) -> Self:
1369
+ """
1370
+ Set connection recycling method.
1371
+
1372
+ Connection recycling method is how a connection is recycled.
1373
+
1374
+ ### Parameters:
1375
+ - `conn_recycling_method`: ConnRecyclingMethod enum.
1376
+
1377
+ ### Returns:
1378
+ `ConnectionPoolBuilder`
1379
+ """
1380
+ def user(self: Self, user: str) -> Self:
1381
+ """
1382
+ Set username to `PostgreSQL`.
1383
+
1384
+ ### Parameters:
1385
+ - `user`: username of the PostgreSQL user.
1386
+
1387
+ ### Returns:
1388
+ `ConnectionPoolBuilder`
1389
+ """
1390
+ def password(self: Self, password: str) -> Self:
1391
+ """
1392
+ Set password for `PostgreSQL`.
1393
+
1394
+ ### Parameters:
1395
+ - `password`: password for the `PostgreSQL` user.
1396
+
1397
+ ### Returns:
1398
+ `ConnectionPoolBuilder`
1399
+ """
1400
+ def dbname(self: Self, dbname: str) -> Self:
1401
+ """
1402
+ Set database name for the `PostgreSQL`.
1403
+
1404
+ ### Parameters:
1405
+ - `dbname`: database for the `PostgreSQL`.
1406
+
1407
+ ### Returns:
1408
+ `ConnectionPoolBuilder`
1409
+ """
1410
+ def options(self: Self, options: str) -> Self:
1411
+ """
1412
+ Set command line options used to configure the server.
1413
+
1414
+ ### Parameters:
1415
+ - `options`: command line options
1416
+
1417
+ ### Returns:
1418
+ `ConnectionPoolBuilder`
1419
+ """
1420
+ def application_name(self: Self, application_name: str) -> Self:
1421
+ """
1422
+ Set the value of the `application_name` runtime parameter.
1423
+
1424
+ ### Parameters:
1425
+ - `application_name`: `application_name` runtime parameter
1426
+
1427
+ ### Returns:
1428
+ `ConnectionPoolBuilder`
1429
+ """
1430
+ def ssl_mode(self: Self, ssl_mode: SslMode) -> Self:
1431
+ """
1432
+ Set the SSL configuration.
1433
+
1434
+ ### Parameters:
1435
+ - `ssl_mode`: mode for TLS.
1436
+
1437
+ ### Returns:
1438
+ `ConnectionPoolBuilder`
1439
+ """
1440
+ def ca_file(self: Self, ca_file: str) -> Self:
1441
+ """
1442
+ Set ca_file for SSL.
1443
+
1444
+ ### Parameters:
1445
+ - `ca_file`: certificate file to connection to PostgreSQL.
1446
+
1447
+ ### Returns:
1448
+ `ConnectionPoolBuilder`
1449
+ """
1450
+ def host(self: Self, host: str) -> Self:
1451
+ """
1452
+ Add a host to the configuration.
1453
+
1454
+ Multiple hosts can be specified by calling this method multiple times,
1455
+ and each will be tried in order.
1456
+ On Unix systems, a host starting with a `/` is interpreted
1457
+ as a path to a directory containing Unix domain sockets.
1458
+ There must be either no hosts,
1459
+ or the same number of hosts as hostaddrs.
1460
+
1461
+ ### Parameters:
1462
+ - `host`: host to `PostgreSQL`.
1463
+
1464
+ ### Returns:
1465
+ `ConnectionPoolBuilder`
1466
+ """
1467
+ def hostaddr(self: Self, hostaddr: IPv4Address | IPv6Address) -> Self:
1468
+ """
1469
+ Add a hostaddr to the configuration.
1470
+
1471
+ Multiple hostaddrs can be specified by calling
1472
+ this method multiple times, and each will be tried in order.
1473
+ There must be either no hostaddrs,
1474
+ or the same number of hostaddrs as hosts.
1475
+
1476
+ ### Parameters:
1477
+ - `hostaddr`: hostaddr to `PostgreSQL`.
1478
+
1479
+ ### Returns:
1480
+ `ConnectionPoolBuilder`
1481
+ """
1482
+ def port(self: Self, port: int) -> Self:
1483
+ """
1484
+ Add a port to the configuration.
1485
+
1486
+ Multiple ports can be specified by calling this method multiple times.
1487
+ There must either be no ports,
1488
+ in which case the default of 5432 is used,
1489
+ a single port, in which it is used for all hosts,
1490
+ or the same number of ports as hosts.
1491
+
1492
+ ### Parameters:
1493
+ - `port`: port for hosts to `PostgreSQL`.
1494
+
1495
+ ### Returns:
1496
+ `ConnectionPoolBuilder`
1497
+ """
1498
+ def connect_timeout(self: Self, connect_timeout: int) -> Self:
1499
+ """
1500
+ Set the timeout applied to socket-level connection attempts.
1501
+
1502
+ Note that hostnames can resolve to multiple IP addresses,
1503
+ and this timeout will apply to each address of each
1504
+ host separately. Defaults to no limit.
1505
+
1506
+ ### Parameters:
1507
+ - `connect_timeout`: connection timeout to `PostgreSQL`.
1508
+
1509
+ ### Returns:
1510
+ `ConnectionPoolBuilder`
1511
+ """
1512
+ def tcp_user_timeout(self: Self, tcp_user_timeout: int) -> Self:
1513
+ """
1514
+ Set the TCP user timeout.
1515
+
1516
+ This is ignored for Unix domain socket connections.
1517
+ It is only supported on systems where TCP_USER_TIMEOUT is available
1518
+ and will default to the system default if omitted or set to 0;
1519
+ on other systems, it has no effect.
1520
+
1521
+ ### Parameters:
1522
+ - `tcp_user_timeout`: tcp_user_timeout to `PostgreSQL`.
1523
+
1524
+ ### Returns:
1525
+ `ConnectionPoolBuilder`
1526
+ """
1527
+ def target_session_attrs(
1528
+ self: Self,
1529
+ target_session_attrs: TargetSessionAttrs,
1530
+ ) -> Self:
1531
+ """
1532
+ Set the requirements of the session.
1533
+
1534
+ This can be used to connect to the primary server in a
1535
+ clustered database rather than one of the read-only
1536
+ secondary servers. Defaults to `Any`.
1537
+
1538
+ ### Parameters:
1539
+ - `target_session_attrs`: target_session_attrs for `PostgreSQL`.
1540
+
1541
+ ### Returns:
1542
+ `ConnectionPoolBuilder`
1543
+ """
1544
+ def load_balance_hosts(
1545
+ self: Self,
1546
+ load_balance_hosts: LoadBalanceHosts,
1547
+ ) -> Self:
1548
+ """
1549
+ Set the host load balancing behavior.
1550
+
1551
+ Defaults to `disable`.
1552
+
1553
+ ### Parameters:
1554
+ - `load_balance_hosts`: load_balance_hosts for `PostgreSQL`.
1555
+
1556
+ ### Returns:
1557
+ `ConnectionPoolBuilder`
1558
+ """
1559
+ def keepalives(
1560
+ self: Self,
1561
+ keepalives: bool,
1562
+ ) -> Self:
1563
+ """
1564
+ Control the use of TCP keepalive.
1565
+
1566
+ This is ignored for Unix domain socket connections.
1567
+
1568
+ Defaults to `true`.
1569
+
1570
+ ### Parameters:
1571
+ - `keepalives`: boolean value for keepalives.
1572
+
1573
+ ### Returns:
1574
+ `ConnectionPoolBuilder`
1575
+ """
1576
+ def keepalives_idle(
1577
+ self: Self,
1578
+ keepalives_idle: int,
1579
+ ) -> Self:
1580
+ """
1581
+ Set the amount of idle time before a keepalive packet is sent on the connection.
1582
+
1583
+ This is ignored for Unix domain sockets,
1584
+ or if the `keepalives` option is disabled.
1585
+
1586
+ Defaults to 2 hours.
1587
+
1588
+ ### Parameters:
1589
+ - `keepalives_idle`: number in secs for idle.
1590
+
1591
+ ### Returns:
1592
+ `ConnectionPoolBuilder`
1593
+ """
1594
+ def keepalives_interval(
1595
+ self: Self,
1596
+ keepalives_interval: int,
1597
+ ) -> Self:
1598
+ """
1599
+ Set the time interval between TCP keepalive probes.
1600
+
1601
+ On Windows, this sets the value of the
1602
+ tcp_keepalive struct keepalive interval field.
1603
+
1604
+ This is ignored for Unix domain sockets,
1605
+ or if the `keepalives` option is disabled.
1606
+
1607
+ ### Parameters:
1608
+ - `keepalives_interval`: number in secs for interval.
1609
+
1610
+ ### Returns:
1611
+ `ConnectionPoolBuilder`
1612
+ """
1613
+ def keepalives_retries(
1614
+ self: Self,
1615
+ keepalives_retries: int,
1616
+ ) -> Self:
1617
+ """Keepalives Retries.
1618
+
1619
+ Set the maximum number of TCP keepalive probes
1620
+ that will be sent before dropping a connection.
1621
+
1622
+ This is ignored for Unix domain sockets,
1623
+ or if the `keepalives` option is disabled.
1624
+
1625
+ ### Parameters:
1626
+ - `keepalives_retries`: number of retries.
1627
+
1628
+ ### Returns:
1629
+ `ConnectionPoolBuilder`
1630
+ """
1631
+
1632
+ class Listener:
1633
+ """Listener for LISTEN command.
1634
+
1635
+ Can be used two ways:
1636
+ 1) As a background task
1637
+ 2) As an asynchronous iterator
1638
+
1639
+ ## Examples
1640
+
1641
+ ### Background task:
1642
+
1643
+ ```python
1644
+ async def callback(
1645
+ channel: str,
1646
+ payload: str,
1647
+ process_id: int,
1648
+ connection: Connection,
1649
+ ) -> None: ...
1650
+ async def main():
1651
+ pool = ConnectionPool()
1652
+
1653
+ listener = pool.listener()
1654
+ await listener.add_callback(
1655
+ channel="test_channel",
1656
+ callback=callback,
1657
+ )
1658
+ await listener.startup()
1659
+
1660
+ listener.listen()
1661
+ ```
1662
+
1663
+ ### Async iterator
1664
+ ```python
1665
+ from psqlpy import
1666
+
1667
+ async def msg_processor(
1668
+ msg: ListenerNotificationMsg,
1669
+ ) -> None:
1670
+ ...
1671
+
1672
+
1673
+ async def main():
1674
+ pool = ConnectionPool()
1675
+
1676
+ listener = pool.listener()
1677
+ await listener.add_callback(
1678
+ channel="test_channel",
1679
+ callback=callback,
1680
+ )
1681
+ await listener.startup()
1682
+
1683
+ for msg in listener:
1684
+ await msg_processor(msg)
1685
+ ```
1686
+ """
1687
+
1688
+ connection: Connection
1689
+ is_started: bool
1690
+
1691
+ def __aiter__(self: Self) -> Self: ...
1692
+ async def __anext__(self: Self) -> ListenerNotificationMsg: ...
1693
+ async def __aenter__(self: Self) -> Self: ...
1694
+ async def __aexit__(
1695
+ self: Self,
1696
+ exception_type: type[BaseException] | None,
1697
+ exception: BaseException | None,
1698
+ traceback: types.TracebackType | None,
1699
+ ) -> None: ...
1700
+ async def startup(self: Self) -> None:
1701
+ """Startup the listener.
1702
+
1703
+ Each listener MUST be started up.
1704
+ """
1705
+ async def shutdown(self: Self) -> None:
1706
+ """Shutdown the listener.
1707
+
1708
+ Abort listen and release underlying connection.
1709
+ """
1710
+ async def add_callback(
1711
+ self: Self,
1712
+ channel: str,
1713
+ callback: Callable[
1714
+ [Connection, str, str, int],
1715
+ Awaitable[None],
1716
+ ],
1717
+ ) -> None:
1718
+ """Add callback to the channel.
1719
+
1720
+ Callback must be async function and have signature like this:
1721
+ ```python
1722
+ async def callback(
1723
+ connection: Connection,
1724
+ payload: str,
1725
+ channel: str,
1726
+ process_id: int,
1727
+ ) -> None: ...
1728
+ ```
1729
+
1730
+ Callback parameters are passed as args on the Rust side.
1731
+ """
1732
+
1733
+ async def clear_channel_callbacks(self, channel: str) -> None:
1734
+ """Remove all callbacks for the channel.
1735
+
1736
+ ### Parameters:
1737
+ - `channel`: name of the channel.
1738
+ """
1739
+
1740
+ async def clear_all_channels(self) -> None:
1741
+ """Clear all channels callbacks."""
1742
+
1743
+ def listen(self: Self) -> None:
1744
+ """Start listening.
1745
+
1746
+ Start actual listening.
1747
+ In the background it creates task in Rust event loop.
1748
+ """
1749
+
1750
+ def abort_listen(self: Self) -> None:
1751
+ """Abort listen.
1752
+
1753
+ If `listen()` method was called, stop listening,
1754
+ else don't do anything.
1755
+ """
1756
+
1757
+ class ListenerNotificationMsg:
1758
+ """Listener message in async iterator."""
1759
+
1760
+ process_id: int
1761
+ channel: str
1762
+ payload: str
1763
+ connection: Connection
1764
+
1765
+ class Column:
1766
+ name: str
1767
+ table_oid: int | None
1768
+
1769
+ class PreparedStatement:
1770
+ async def execute(self: Self) -> QueryResult:
1771
+ """Execute prepared statement."""
1772
+ def cursor(self: Self) -> Cursor:
1773
+ """Create new server-side cursor based on prepared statement."""
1774
+ def columns(self: Self) -> list[Column]:
1775
+ """Return information about statement columns."""