asyncqlio’s low-level API is a database-agnostic SQL API that provides developers the ability to execute SQL code without worrying about the underlying driver.
from asyncqlio.db import DatabaseInterface
# create the database object to connect to the server.
db = DatabaseInterface("postgresql+asyncpg://joku@127.0.0.1/joku")
async def main():
# connect to the database with db.connect
await db.connect()
# create a transaction to execute sql inside of
async with db.get_transaction() as trans:
# run a query
results: BaseResultSet = await trans.cursor("SELECT 1;")
row = await results.fetch_row() # row with 1
Transactions are the way of executing queries without affecting the rest of the database. All agnostic connections require the usage of a transaction to execute SQL (it is possible to execute SQL purely on a connection using the driver-specific API, but this is not supported).
The BaseTransaction
object is used to abstract away Database API
transaction objects into a common format that can be used in every dialect.
To get a new transaction that is bound to the current connection, use
DatabaseInterface.get_transaction()
:
# tr is a new transaction object
tr: BaseTransaction = db.get_transaction()
# this is connected to the current database's connections
# and will execute on said connection
Transactions MUST be started before execution can happen; this can be achieved
with BaseTransaction.begin()
.
# start the transaction
# this will usually emit a BEGIN or START TRANSACTION command underneath
await tr.begin()
SQL can be emitted in the transaction with the usage of
BaseTransaction.execute()
and BaseTransaction.cursor()
.
# update some data
await tr.execute('UPDATE "user" SET level = 3 WHERE "user".xp < 1000')
# select some rows
rows = await tr.cursor('SELECT * FROM "user" WHERE level > 5')
BaseTransaction.cursor()
returns rows from a select query in the
form of a BaseResultSet()
. ResultSets can be iterated over
asynchronously with async for
to select each dict-like row:
async for row in rows:
print(row.keys(), row.values())
Once done with the transaction, you can commit it to flush the changes, or you can rollback to revert any changes.
if all_went_good:
# it all went good, save changes
await tr.commit()
else:
# not all went good, rollback changes
await tr.rollback()
Transactions support the async for
protocol, which will automatically
begin and commit/rollback as appropriate.
asyncqlio.backends.base.
BaseTransaction
(connector: asyncqlio.backends.base.BaseConnector)[source]¶Bases: asyncqlio.meta.AsyncABC
The base class for a transaction. This represents a database transaction (i.e SQL statements guarded with a BEGIN and a COMMIT/ROLLBACK).
Children classes must implement:
Additionally, some extra methods can be implemented:
These methods are not required to be implemented, but will raise NotImplementedError
if
they are not.
This class takes one parameter in the constructor: the BaseConnector
used to connect
to the DB server.
rollback
(checkpoint: str = None)[source]¶Rolls back the transaction.
Parameters: | checkpoint – If provided, the checkpoint to rollback to. Otherwise, the entire transaction will be rolled back. |
---|
execute
(sql: str, params: typing.Iterable = None)[source]¶Executes SQL in the current transaction.
Parameters: |
|
---|
cursor
(sql: str, params: typing.Iterable = None) → asyncqlio.backends.base.BaseResultSet[source]¶Executes SQL and returns a database cursor for the rows.
Parameters: |
|
---|---|
Returns: | The |
create_savepoint
(name: str)[source]¶Creates a savepoint in the current transaction.
Warning
This is not supported in all DB engines. If so, this will raise
NotImplementedError
.
Parameters: | name – The name of the savepoint to create. |
---|
asyncqlio.backends.base.
BaseResultSet
[source]¶Bases: collections.abc.AsyncIterator
, asyncqlio.meta.AsyncABC
The base class for a result set. This represents the results from a database query, as an async iterable.
Children classes must implement:
BaseResultSet.keys
BaseResultSet.fetch_row
BaseResultSet.fetch_many
keys
¶Returns: | An iterable of keys that this query contained. |
---|
fetch_row
() → typing.Mapping[str, typing.Any][source]¶Fetches the next row in this query.
This should return None if the row could not be fetched.