Skip to content

Commit aee906d

Browse files
authored
Merge pull request #24 from qaspen-python/connection_missing_methods
Add execute_many, fetch_row, fetch_val to connection; impove docstrings
2 parents 75b587b + 3835fb3 commit aee906d

File tree

13 files changed

+614
-344
lines changed

13 files changed

+614
-344
lines changed

README.md

Lines changed: 7 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -109,8 +109,6 @@ db_pool = PSQLPool(
109109
)
110110

111111
async def main() -> None:
112-
await db_pool.startup()
113-
114112
res: QueryResult = await db_pool.execute(
115113
"SELECT * FROM users",
116114
)
@@ -147,10 +145,12 @@ As connection can be closed in different situations on various sides you can sel
147145
rendered ineffective.
148146

149147
## Results from querying
148+
150149
You have some options to get results from the query.
151150
`execute()` method, for example, returns `QueryResult` and this class can be converted into `list` of `dict`s - `list[dict[Any, Any]]` or into any Python class (`pydantic` model, as an example).
152151

153152
Let's see some code:
153+
154154
```python
155155
from typing import Any
156156

@@ -169,8 +169,6 @@ db_pool = PSQLPool(
169169
)
170170

171171
async def main() -> None:
172-
await db_pool.startup()
173-
174172
res: QueryResult = await db_pool.execute(
175173
"SELECT * FROM users",
176174
)
@@ -213,8 +211,6 @@ db_pool = PSQLPool(
213211
)
214212

215213
async def main() -> None:
216-
await db_pool.startup()
217-
218214
connection = await db_pool.connection()
219215

220216
res: QueryResult = await connection.execute(
@@ -252,8 +248,6 @@ from psqlpy import PSQLPool, IsolationLevel, QueryResult
252248
db_pool = PSQLPool()
253249

254250
async def main() -> None:
255-
await db_pool.startup()
256-
257251
connection = await db_pool.connection()
258252
async with connection.transaction() as transaction:
259253
res: QueryResult = await transaction.execute(
@@ -276,8 +270,6 @@ from psqlpy import PSQLPool, IsolationLevel
276270
db_pool = PSQLPool()
277271

278272
async def main() -> None:
279-
await db_pool.startup()
280-
281273
connection = await db_pool.connection()
282274
transaction = connection.transaction(
283275
isolation_level=IsolationLevel.Serializable,
@@ -310,8 +302,6 @@ from psqlpy import PSQLPool, IsolationLevel
310302
db_pool = PSQLPool()
311303

312304
async def main() -> None:
313-
await db_pool.startup()
314-
315305
connection = await db_pool.connection()
316306
transaction = connection.transaction(
317307
isolation_level=IsolationLevel.Serializable,
@@ -339,8 +329,6 @@ from psqlpy import PSQLPool, IsolationLevel
339329
db_pool = PSQLPool()
340330

341331
async def main() -> None:
342-
await db_pool.startup()
343-
344332
connection = await db_pool.connection()
345333
transaction = connection.transaction(
346334
isolation_level=IsolationLevel.Serializable,
@@ -367,8 +355,6 @@ from psqlpy import PSQLPool, IsolationLevel
367355
db_pool = PSQLPool()
368356

369357
async def main() -> None:
370-
await db_pool.startup()
371-
372358
connection = await db_pool.connection()
373359
transaction = connection.transaction(
374360
isolation_level=IsolationLevel.Serializable,
@@ -383,13 +369,15 @@ async def main() -> None:
383369
```
384370

385371
### Transaction pipelining
372+
386373
When you have a lot of independent queries and want to execute them concurrently, you can use `pipeline`.
387374
Pipelining can improve performance in use cases in which multiple,
388375
independent queries need to be executed.
389376
In a traditional workflow,
390377
each query is sent to the server after the previous query completes.
391378
In contrast, pipelining allows the client to send all of the queries to the server up front,
392379
minimizing time spent by one side waiting for the other to finish sending data:
380+
393381
```
394382
Sequential Pipelined
395383
| Client | Server | | Client | Server |
@@ -404,9 +392,11 @@ minimizing time spent by one side waiting for the other to finish sending data:
404392
| | process query 3 |
405393
| receive rows 3 | |
406394
```
395+
407396
Read more: https://docs.rs/tokio-postgres/latest/tokio_postgres/#pipelining
408397

409398
Let's see some code:
399+
410400
```python
411401
import asyncio
412402

@@ -415,8 +405,6 @@ from psqlpy import PSQLPool, QueryResult
415405

416406
async def main() -> None:
417407
db_pool = PSQLPool()
418-
await db_pool.startup()
419-
420408
transaction = await db_pool.transaction()
421409

422410
results: list[QueryResult] = await transaction.pipeline(
@@ -450,8 +438,6 @@ from psqlpy import PSQLPool, IsolationLevel
450438
db_pool = PSQLPool()
451439

452440
async def main() -> None:
453-
await db_pool.startup()
454-
455441
connection = await db_pool.connection()
456442
transaction = connection.transaction(
457443
isolation_level=IsolationLevel.Serializable,
@@ -484,8 +470,6 @@ from psqlpy import PSQLPool, IsolationLevel
484470
db_pool = PSQLPool()
485471

486472
async def main() -> None:
487-
await db_pool.startup()
488-
489473
connection = await db_pool.connection()
490474
transaction = connection.transaction(
491475
isolation_level=IsolationLevel.Serializable,
@@ -524,8 +508,6 @@ from psqlpy import PSQLPool, IsolationLevel, QueryResult
524508
db_pool = PSQLPool()
525509

526510
async def main() -> None:
527-
await db_pool.startup()
528-
529511
connection = await db_pool.connection()
530512
transaction = connection.transaction(
531513
isolation_level=IsolationLevel.Serializable,
@@ -553,6 +535,7 @@ async def main() -> None:
553535
```
554536

555537
### Cursor as an async context manager
538+
556539
```python
557540
from typing import Any
558541

@@ -563,8 +546,6 @@ db_pool = PSQLPool()
563546

564547

565548
async def main() -> None:
566-
await db_pool.startup()
567-
568549
connection = await db_pool.connection()
569550
transaction: Transaction
570551
cursor: Cursor
@@ -624,8 +605,6 @@ from psqlpy.extra_types import (
624605
db_pool = PSQLPool()
625606

626607
async def main() -> None:
627-
await db_pool.startup()
628-
629608
res: list[dict[str, Any]] = await db_pool.execute(
630609
"INSERT INTO users VALUES ($1, $2, $3, $4, $5)",
631610
[

docs/examples/aiohttp/start_example.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# Start example
22
import asyncio
3-
from typing import cast
3+
from typing import Any, cast
4+
45
from aiohttp import web
56
from psqlpy import PSQLPool
67

@@ -11,7 +12,6 @@ async def start_db_pool(app: web.Application) -> None:
1112
dsn="postgres://postgres:postgres@localhost:5432/postgres",
1213
max_db_pool_size=2,
1314
)
14-
await db_pool.startup()
1515

1616
app["db_pool"] = db_pool
1717

@@ -22,7 +22,7 @@ async def stop_db_pool(app: web.Application) -> None:
2222
await db_pool.close()
2323

2424

25-
async def pg_pool_example(request: web.Request):
25+
async def pg_pool_example(request: web.Request) -> Any:
2626
db_pool = cast(PSQLPool, request.app["db_pool"])
2727
connection = await db_pool.connection()
2828
await asyncio.sleep(10)
@@ -37,7 +37,7 @@ async def pg_pool_example(request: web.Request):
3737

3838
application = web.Application()
3939
application.on_startup.append(start_db_pool)
40-
application.add_routes([web.get('/', pg_pool_example)])
40+
application.add_routes([web.get("/", pg_pool_example)])
4141

4242

4343
if __name__ == "__main__":

docs/examples/fastapi/advanced_example.py

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
# Start example
22
import asyncio
33
from contextlib import asynccontextmanager
4-
from typing import Annotated, AsyncGenerator, cast
5-
from fastapi import Depends, FastAPI, Request
6-
from fastapi.responses import JSONResponse
7-
from psqlpy import PSQLPool, Connection
8-
import uvicorn
4+
from typing import AsyncGenerator
95

6+
import uvicorn
7+
from fastapi import FastAPI
8+
from fastapi.responses import JSONResponse
9+
from psqlpy import PSQLPool
1010

1111
db_pool = PSQLPool(
1212
dsn="postgres://postgres:postgres@localhost:5432/postgres",
@@ -17,7 +17,6 @@
1717
@asynccontextmanager
1818
async def lifespan(app: FastAPI) -> AsyncGenerator[None, None]:
1919
"""Startup database connection pool and close it on shutdown."""
20-
await db_pool.startup()
2120
app.state.db_pool = db_pool
2221
yield
2322
await db_pool.close()
@@ -34,7 +33,7 @@ async def some_long_func() -> None:
3433

3534

3635
@app.get("/")
37-
async def pg_pool_example():
36+
async def pg_pool_example() -> JSONResponse:
3837
await some_long_func()
3938
db_connection = await db_pool.connection()
4039
query_result = await db_connection.execute(
@@ -47,4 +46,4 @@ async def pg_pool_example():
4746
uvicorn.run(
4847
"advanced_example:app",
4948
port=8001,
50-
)
49+
)

docs/examples/fastapi/start_example.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
# Start example
22
from contextlib import asynccontextmanager
3-
from typing import Annotated, AsyncGenerator, cast
3+
from typing import AsyncGenerator, cast
4+
5+
import uvicorn
46
from fastapi import Depends, FastAPI, Request
57
from fastapi.responses import JSONResponse
6-
from psqlpy import PSQLPool, Connection
7-
import uvicorn
8+
from psqlpy import Connection, PSQLPool
9+
from typing_extensions import Annotated
810

911

1012
@asynccontextmanager
@@ -14,7 +16,6 @@ async def lifespan(app: FastAPI) -> AsyncGenerator[None, None]:
1416
dsn="postgres://postgres:postgres@localhost:5432/postgres",
1517
max_db_pool_size=2,
1618
)
17-
await db_pool.startup()
1819
app.state.db_pool = db_pool
1920
yield
2021
await db_pool.close()
@@ -31,7 +32,7 @@ async def db_connection(request: Request) -> Connection:
3132
@app.get("/")
3233
async def pg_pool_example(
3334
db_connection: Annotated[Connection, Depends(db_connection)],
34-
):
35+
) -> JSONResponse:
3536
query_result = await db_connection.execute(
3637
"SELECT * FROM users",
3738
)
@@ -41,4 +42,4 @@ async def pg_pool_example(
4142
if __name__ == "__main__":
4243
uvicorn.run(
4344
"start_example:app",
44-
)
45+
)

0 commit comments

Comments
 (0)