Aiopg
aiopg is a library for accessing a PostgreSQL database from the asyncio (PEP-3156/tulip) framework. It wraps asynchronous features of the Psycopg database driver. The current version is 1.4.0, and it is actively maintained by the aio-libs organization, though the last release was in October 2022.
Warnings
- breaking aiopg internally uses `psycopg2-binary` connections in `autocommit=True` mode for asynchronous operations. This means `conn.commit()` and `conn.rollback()` methods are disabled and will raise `psycopg2.ProgrammingError`. Transactions must be explicitly managed by executing `BEGIN` and `COMMIT`/`ROLLBACK` SQL statements manually.
- gotcha Almost all connection and cursor methods in aiopg are coroutines and *must* be `await`ed. However, `Cursor.mogrify()` specifically had its `await` requirement removed in a later version and should now be called synchronously.
- deprecated Iteration protocol support in `cursor` and `ResultProxy` was deprecated in version 0.7.0. While still functional for older codebases, relying on direct iteration for results might lead to unexpected behavior or future breakage.
- gotcha aiopg requires Python 3.7+ and only supports the `async/await` syntax. Older `asyncio` patterns (e.g., `@asyncio.coroutine` decorators) are not supported.
- gotcha When creating a cursor via `conn.cursor()`, some parameters like `name`, `scrollable`, and `withhold` are not supported by `psycopg2-binary` in asynchronous mode and will be ignored or raise errors if specified. Only `cursor_factory` and `timeout` are reliably supported.
Install
-
pip install aiopg -
pip install aiopg[sa]
Imports
- aiopg
import aiopg
- create_pool
import aiopg await aiopg.create_pool(...)
- create_engine
from aiopg.sa import create_engine
Quickstart
import asyncio
import aiopg
import os
dsn = os.environ.get('AIOPG_DSN', 'dbname=aiopg user=aiopg password=passwd host=127.0.0.1')
async def main():
# Establish a connection pool
async with aiopg.create_pool(dsn) as pool:
# Acquire a connection from the pool
async with pool.acquire() as conn:
# Open a cursor to perform database operations
async with conn.cursor() as cur:
# Execute a simple query
await cur.execute("SELECT 1")
ret = []
# Iterate over the results
async for row in cur:
ret.append(row)
assert ret == [(1,)]
print(f"Query result: {ret}")
if __name__ == '__main__':
# For Python 3.10+
try:
asyncio.run(main())
except RuntimeError as e:
if "cannot run an event loop while another loop is running" in str(e):
# Handle cases where an event loop might already be running (e.g., in notebooks)
loop = asyncio.get_event_loop()
if loop.is_running():
loop.create_task(main())
else:
loop.run_until_complete(main())
else:
raise