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