Welcome to triopg!
PostgreSQL client for Trio based on asyncpg.
License: Your choice of MIT or Apache License 2.0
Quick example:
import trio_asyncio
import triopg
async def main():
async with triopg.connect() as conn:
await conn.execute(
"""
DROP TABLE IF EXISTS users;
CREATE TABLE IF NOT EXISTS users (
_id SERIAL PRIMARY KEY,
user_id VARCHAR(32) UNIQUE
)"""
)
async with conn.transaction():
await conn.execute("INSERT INTO users (user_id) VALUES (1)")
await conn.execute("INSERT INTO users (user_id) VALUES (2)")
await conn.execute("INSERT INTO users (user_id) VALUES (3)")
print(await conn.fetch("SELECT * FROM users"))
trio_asyncio.run(main)
triopg
is a thin Trio-compatible wrapper around asyncpg
. The API is the same,
with one exception - triopg
does not support manual resource management.
In asyncpg
you can manage pools, connections and transactions manually:
conn = await asyncpg.connect()
tr = conn.transaction()
# ..
tr.commit()
conn.close()
While in triopg
you can only use async with
blocks:
async with triopg.connect() as conn:
async with conn.transaction():
# ...
Otherwise you can follow asyncpg
tutorial and
reference.
Everything should work the same way. Please
file an issue if it doesn't.
In addition to asyncpg
-compatible API, triopg
provides Trio-style
.listen()
helper for the eponymous
Postgres statement:
async with conn.listen('some.channel', max_buffer_size=1) as notifications:
async for notification in notifications:
if notification != triopg.NOTIFY_OVERFLOW:
print('Notification received:', notification)
max_buffer_size
is the amount of notifications you are willing to queue in memory.
If you don't want to think about buffering, set the buffer size to math.inf
and everything will just work in regular non-pathological situations.
Otherwise, you can set a finite buffer. In this case you should handle
triopg.NOTIFY_OVERFLOW
marker and react according to your use case.
For example, you could re-scan the tables, like you would do at startup.
Or could you simply ignore the marker if you are only interested in the
newest notifications.
For detailed discussion on buffering, see Trio manual, "Buffering in channels" section.
Note: we can't politely ask Postgres to slow down: LISTEN
backpressure is
not supported by asyncpg.
There's also an inherent challenge with Postgres. Postgres (like most
broadcast systems) doesn't really have a good way to communicate backpressure
further upstream to the clients that are calling NOTIFY
.